salt-parser 0.0.2 → 0.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.
- checksums.yaml +4 -4
- data/Gemfile +1 -0
- data/Gemfile.lock +2 -0
- data/{README.rdoc → README.md} +13 -12
- data/Rakefile +3 -0
- data/lib/salt-parser/base.rb +1 -0
- data/lib/salt-parser/errors.rb +2 -0
- data/lib/salt-parser/version.rb +2 -2
- data/lib/swift/account.rb +46 -0
- data/lib/swift/accounts.rb +6 -0
- data/lib/swift/builder.rb +12 -0
- data/lib/swift/dependencies.rb +10 -0
- data/lib/swift/parser.rb +56 -0
- data/lib/swift/supported_fields.rb +10 -0
- data/lib/swift/transaction.rb +54 -0
- data/lib/swift/transaction_info.rb +62 -0
- data/salt-parser.gemspec +4 -2
- data/spec/swift/fixtures/barclays.txt +27 -0
- data/spec/swift/fixtures/empty_86.txt +2 -0
- data/spec/swift/fixtures/empty_line.txt +4 -0
- data/spec/swift/fixtures/sepa_mt9401.txt +49 -0
- data/spec/swift/fixtures/test.txt +16 -0
- data/spec/swift/fixtures/unknown_data.txt +4 -0
- data/spec/swift/fixtures/with_binary_character.txt +27 -0
- data/spec/swift/parser_spec.rb +118 -0
- metadata +23 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6015ab5f8ce681a933de914c88a31dc030971a47
|
4
|
+
data.tar.gz: 7bcbaee9158fc724a575b005a8b4fa922dc27f8d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e727e547cd67dde1affad73c69e7777c7bcc3a9df2c2f55d49f42a9d53ca312bd2183f96078515ccff126d2cc81d3a161c38efcf291eeb048ec9ac85f1515786
|
7
|
+
data.tar.gz: f8600fcadd8aa638e187dfd6a082c51b132f7cb46dd6bea77e9aa5086e6a77c4d67254fcdcd95d8f2a6dc144e5d9ab396b8a4ecbe5d8cf85bb898be3d1a96ee3
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -37,6 +37,7 @@ GEM
|
|
37
37
|
byebug (~> 2.7)
|
38
38
|
pry (~> 0.10)
|
39
39
|
rack (1.6.4)
|
40
|
+
rake (10.4.2)
|
40
41
|
rest-client (1.8.0)
|
41
42
|
http-cookie (>= 1.0.2, < 2.0)
|
42
43
|
mime-types (>= 1.16, < 3.0)
|
@@ -78,6 +79,7 @@ DEPENDENCIES
|
|
78
79
|
nokogiri
|
79
80
|
pry-byebug (~> 1.3.2)
|
80
81
|
rack
|
82
|
+
rake
|
81
83
|
rest-client
|
82
84
|
rspec
|
83
85
|
simplecov
|
data/{README.rdoc → README.md}
RENAMED
@@ -1,26 +1,27 @@
|
|
1
|
-
|
1
|
+
### Salt Parser
|
2
2
|
|
3
|
-
Library for parsing OFX,
|
3
|
+
Library for parsing OFX, QIF and SWIFT formats.
|
4
4
|
|
5
|
-
|
5
|
+
### Install
|
6
6
|
|
7
|
-
|
7
|
+
```ruby
|
8
|
+
gem install salt-parser
|
9
|
+
```
|
8
10
|
|
9
11
|
|
10
|
-
|
11
|
-
-
|
12
|
-
- Add HBCI parser
|
13
|
-
- Add code examples
|
12
|
+
### Examples:
|
13
|
+
- Could be found in specs
|
14
14
|
|
15
|
-
|
15
|
+
### Credits
|
16
16
|
|
17
17
|
Special thanks to:
|
18
18
|
|
19
|
-
- @annacruz (
|
20
|
-
- @jemmyw (
|
19
|
+
- @annacruz [ofx](https://github.com/annacruz/ofx)
|
20
|
+
- @jemmyw [qif](https://github.com/jemmyw/Qif)
|
21
|
+
- @betterplace [swift](https://github.com/betterplace/mt940_parser)
|
21
22
|
|
22
23
|
|
23
|
-
|
24
|
+
### License
|
24
25
|
|
25
26
|
(The MIT License)
|
26
27
|
|
data/Rakefile
CHANGED
data/lib/salt-parser/base.rb
CHANGED
data/lib/salt-parser/errors.rb
CHANGED
@@ -8,6 +8,8 @@ module SaltParser
|
|
8
8
|
FLOAT = "Error while parsing float field."
|
9
9
|
end
|
10
10
|
class RequestError < StandardError; end
|
11
|
+
class UnsupportedTag < StandardError; end
|
12
|
+
class WrongLineFormat < StandardError; end
|
11
13
|
class UnsupportedDateFormat < StandardError; end
|
12
14
|
class UnsupportedFileError < StandardError; end
|
13
15
|
end
|
data/lib/salt-parser/version.rb
CHANGED
@@ -0,0 +1,46 @@
|
|
1
|
+
module SaltParser
|
2
|
+
module Swift
|
3
|
+
class Account < SaltParser::Base
|
4
|
+
attr_accessor :account_identification, :closing_balance, :transactions
|
5
|
+
|
6
|
+
BALANCE_TYPE = {
|
7
|
+
"F" => :start,
|
8
|
+
"M" => :intermediate
|
9
|
+
}
|
10
|
+
SIGN = {
|
11
|
+
"C" => :credit,
|
12
|
+
"D" => :debit
|
13
|
+
}
|
14
|
+
|
15
|
+
def initialize
|
16
|
+
@transactions = []
|
17
|
+
end
|
18
|
+
|
19
|
+
def to_hash
|
20
|
+
{
|
21
|
+
:account_identification => account_identification,
|
22
|
+
:closing_balance => closing_balance,
|
23
|
+
:transactions => transactions.map(&:to_hash)
|
24
|
+
}
|
25
|
+
end
|
26
|
+
|
27
|
+
def parse_account_identification(options)
|
28
|
+
@account_identification = options[:content]
|
29
|
+
end
|
30
|
+
|
31
|
+
def parse_closing_balance(options)
|
32
|
+
match_data = options[:content].match(/^(?<sign>C|D)(?<raw_date>\w{6})(?<currency>\w{3})(?<amount>\d{1,12},\d{0,2})$/) || {}
|
33
|
+
hash = {}
|
34
|
+
hash[:balance_type] = BALANCE_TYPE[options[:modifier]]
|
35
|
+
hash[:sign] = SIGN[match_data[:sign]]
|
36
|
+
hash[:currency] = match_data[:currency]
|
37
|
+
hash[:amount] = match_data[:amount].gsub(',', '').to_i #amount in cents
|
38
|
+
|
39
|
+
date = match_data[:raw_date].match(/(?<year>\d{2})(?<month>\d{2})(?<day>\d{2})/) rescue nil
|
40
|
+
hash[:date] = Date.new(2000 + date[:year].to_i, date[:month].to_i, date[:day].to_i) rescue nil
|
41
|
+
|
42
|
+
@closing_balance = hash
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module SaltParser
|
2
|
+
module Swift
|
3
|
+
class Builder < SaltParser::Builder
|
4
|
+
def initialize(resource)
|
5
|
+
resource = open_resource(resource)
|
6
|
+
resource.rewind
|
7
|
+
|
8
|
+
@parser = SaltParser::Swift::Parser.new(:data => convert_to_utf8(resource.read))
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
require "date"
|
2
|
+
require "active_support/core_ext"
|
3
|
+
|
4
|
+
require_relative "builder"
|
5
|
+
require_relative "account"
|
6
|
+
require_relative "accounts"
|
7
|
+
require_relative "transaction"
|
8
|
+
require_relative "transaction_info"
|
9
|
+
require_relative "supported_fields"
|
10
|
+
require_relative "parser"
|
data/lib/swift/parser.rb
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
module SaltParser
|
2
|
+
module Swift
|
3
|
+
class Parser
|
4
|
+
attr_reader :accounts, :errors
|
5
|
+
|
6
|
+
def initialize(options = {})
|
7
|
+
@accounts = SaltParser::Swift::Accounts.new
|
8
|
+
@errors = []
|
9
|
+
parse(options[:data])
|
10
|
+
end
|
11
|
+
|
12
|
+
def parse(text)
|
13
|
+
new_text = text.strip
|
14
|
+
new_text << "\r\n" if new_text[-1,1] == "-"
|
15
|
+
|
16
|
+
accounts_rows = new_text.split(/^-\r\n/)
|
17
|
+
accounts_rows.map do |row|
|
18
|
+
account = SaltParser::Swift::Account.new
|
19
|
+
raw_sheet = row.gsub(/\r\n(?!:)/, "")
|
20
|
+
parse_sheet(account, raw_sheet)
|
21
|
+
@accounts << account
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def parse_sheet(account, sheet)
|
28
|
+
lines = sheet.split("\r\n").reject(&:empty?)
|
29
|
+
lines.map do |line|
|
30
|
+
if match_data = line.match(/^:(?<tag>\d{2})(?<modifier>\w)?:(?<content>.*)$/)
|
31
|
+
begin
|
32
|
+
next unless item = SaltParser::Swift::SUPPORTED_FIELDS[match_data[:tag]]
|
33
|
+
options = {:content => match_data[:content], :modifier => match_data[:modifier]}
|
34
|
+
|
35
|
+
case item["type"]
|
36
|
+
when "closing_balance"
|
37
|
+
account.parse_closing_balance(options)
|
38
|
+
when "account_identification"
|
39
|
+
account.parse_account_identification(options)
|
40
|
+
when "transaction"
|
41
|
+
account.transactions.push(SaltParser::Swift::Transaction.new(options))
|
42
|
+
when "transaction_info"
|
43
|
+
account.transactions.last.try("info=".to_sym, SaltParser::Swift::TransactionInfo.new(options))
|
44
|
+
end
|
45
|
+
rescue SaltParser::Error => error
|
46
|
+
errors << error
|
47
|
+
next
|
48
|
+
end
|
49
|
+
else
|
50
|
+
errors << SaltParser::Error::WrongLineFormat
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module SaltParser
|
2
|
+
module Swift
|
3
|
+
class Transaction
|
4
|
+
attr_accessor :info
|
5
|
+
attr_reader :date, :entry_date, :funds_code, :amount,
|
6
|
+
:swift_code, :reference, :transaction_description
|
7
|
+
|
8
|
+
FUNDS_CORE = {
|
9
|
+
"C" => :credit,
|
10
|
+
"D" => :debit,
|
11
|
+
"RC" => :return_credit,
|
12
|
+
"RD" => :return_debit
|
13
|
+
}
|
14
|
+
|
15
|
+
def initialize(options)
|
16
|
+
match_data = options[:content].match(/^(?<raw_date>\d{6})(?<raw_entry_date>\d{4})?(?<funds_code>C|D|RC|RD)\D?(?<amount>\d{1,12},\d{0,2})(?<swift_code>(?:N|F).{3})(?<reference>NONREF|.{0,16})($|\/\/)(?<transaction_description>.*)/) || {}
|
17
|
+
|
18
|
+
@funds_code = FUNDS_CORE[match_data[:funds_code]]
|
19
|
+
@amount = match_data[:amount].gsub(',', '').to_i # amount in cents
|
20
|
+
@swift_code = match_data[:swift_code]
|
21
|
+
@reference = match_data[:reference]
|
22
|
+
@transaction_description = match_data[:transaction_description]
|
23
|
+
|
24
|
+
@date = parse_date(match_data[:raw_date])
|
25
|
+
@entry_date = parse_entry_date(match_data[:raw_entry_date], @date) if match_data[:raw_entry_date]
|
26
|
+
end
|
27
|
+
|
28
|
+
def to_hash
|
29
|
+
{
|
30
|
+
:date => date,
|
31
|
+
:entry_date => entry_date,
|
32
|
+
:funds_code => funds_code,
|
33
|
+
:amount => amount,
|
34
|
+
:swift_code => swift_code,
|
35
|
+
:reference => reference,
|
36
|
+
:transaction_description => transaction_description,
|
37
|
+
:info => info.try(:to_hash)
|
38
|
+
}
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def parse_date(date)
|
44
|
+
match_data = date.match(/(?<year>\d{2})(?<month>\d{2})(?<day>\d{2})/)
|
45
|
+
Date.new(2000 + match_data[:year].to_i, match_data[:month].to_i, match_data[:day].to_i)
|
46
|
+
end
|
47
|
+
|
48
|
+
def parse_entry_date(raw_entry_date, value_date)
|
49
|
+
match_data = raw_entry_date.match(/(?<month>\d{2})(?<day>\d{2})/)
|
50
|
+
Date.new(value_date.year, match_data[:month].to_i, match_data[:day].to_i)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module SaltParser
|
2
|
+
module Swift
|
3
|
+
class TransactionInfo
|
4
|
+
attr_reader :code, :transaction_description, :prima_nota, :details,
|
5
|
+
:bank_code, :account_number, :account_holder,
|
6
|
+
:text_key_extension, :not_implemented_fields
|
7
|
+
|
8
|
+
def initialize(options)
|
9
|
+
match_data = options[:content].match(/^(?<code>\d{3})(?<sub_fields>(?<seperator>.).*)$/)
|
10
|
+
if match_data
|
11
|
+
@code = match_data[:code].to_i
|
12
|
+
details, account_holder = [], []
|
13
|
+
|
14
|
+
if seperator = match_data[:seperator]
|
15
|
+
sub_fields = match_data[:sub_fields].scan(/#{Regexp.escape(seperator)}(\d{2})([^#{Regexp.escape(seperator)}]*)/)
|
16
|
+
|
17
|
+
sub_fields.each do |(code, content)|
|
18
|
+
case code.to_i
|
19
|
+
when 0
|
20
|
+
@transaction_description = content
|
21
|
+
when 10
|
22
|
+
@prima_nota = content
|
23
|
+
when 20..29, 60..63
|
24
|
+
details << content
|
25
|
+
when 30
|
26
|
+
@bank_code = content
|
27
|
+
when 31
|
28
|
+
@account_number = content
|
29
|
+
when 32..33
|
30
|
+
account_holder << content
|
31
|
+
when 34
|
32
|
+
@text_key_extension = content
|
33
|
+
else
|
34
|
+
@not_implemented_fields ||= []
|
35
|
+
@not_implemented_fields << [code, content]
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
@details = details.join("\n")
|
41
|
+
@account_holder = account_holder.join("\n")
|
42
|
+
else
|
43
|
+
@details = options[:content]
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def to_hash
|
48
|
+
{
|
49
|
+
:code => code,
|
50
|
+
:transaction_description => transaction_description,
|
51
|
+
:prima_nota => prima_nota,
|
52
|
+
:details => details,
|
53
|
+
:bank_code => bank_code,
|
54
|
+
:account_number => account_number,
|
55
|
+
:account_holder => account_holder,
|
56
|
+
:text_key_extension => text_key_extension,
|
57
|
+
:not_implemented_fields => not_implemented_fields
|
58
|
+
}
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
data/salt-parser.gemspec
CHANGED
@@ -9,14 +9,16 @@ Gem::Specification.new do |s|
|
|
9
9
|
s.authors = ["saltedge team"]
|
10
10
|
s.email = ["support@saltedge.com"]
|
11
11
|
s.homepage = "http://saltedge.com"
|
12
|
-
s.summary = "Gem for parsing OFX,
|
13
|
-
s.description = "Gem for parsing OFX,
|
12
|
+
s.summary = "Gem for parsing OFX, QIF and SWIFT formats."
|
13
|
+
s.description = "Gem for parsing OFX, QIF and SWIFT formats."
|
14
14
|
s.files = `git ls-files`.split("\n")
|
15
15
|
s.test_files = `git ls-files -- {spec}/*`.split("\n")
|
16
16
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |file| File.basename(f) }
|
17
17
|
s.require_paths = ["lib"]
|
18
18
|
s.licenses = ["MIT"]
|
19
19
|
|
20
|
+
s.metadata = { "issue_tracker" => "https://github.com/saltedge/salt-parser/issues" }
|
21
|
+
|
20
22
|
s.add_dependency "nokogiri"
|
21
23
|
s.add_development_dependency "rspec", "~> 3.0"
|
22
24
|
s.add_development_dependency 'bundler', '~> 1.3'
|
@@ -0,0 +1,27 @@
|
|
1
|
+
:20:33444
|
2
|
+
:25:USD:555:7777777
|
3
|
+
:28C:35397/1
|
4
|
+
:60F:C120104USD31332,33
|
5
|
+
:61:1201250125DD25,00FTRFSUB FEE BI//0
|
6
|
+
:61:1201250125DD25,00FTRFN/A//0
|
7
|
+
:86:LEDGER FEES
|
8
|
+
:61:1201270127CC475,00FTRF200//0
|
9
|
+
:86:BILL PAYMENT
|
10
|
+
:61:1201270127DD4,00FTRF200//0
|
11
|
+
:61:1202210221DD560,00FTRF201//0
|
12
|
+
:86:BILL PAYMENT
|
13
|
+
:61:1202210221DD4,00FTRF201//0
|
14
|
+
:61:1202240224DD25,00FCOMSUB_FEE_BI//0
|
15
|
+
:86:COMMISSION
|
16
|
+
:61:1202240224DD25,00FTRFN/A//0
|
17
|
+
:86:LEDGER FEES
|
18
|
+
:61:1203240324DD25,00FTRFN/A//0
|
19
|
+
:86:LEDGER FEES
|
20
|
+
:61:1203270327DD25,00FCOMSUB_FEE_BI//0
|
21
|
+
:86:COMMISSION
|
22
|
+
:61:1204240424DD25,00FCOMSUB_FEE_BI//0
|
23
|
+
:86:COMMISSION
|
24
|
+
:62F:C120424USD30114,33
|
25
|
+
:64:C120424USD30114,33
|
26
|
+
:65:C120424USD30114,33
|
27
|
+
:86:Flat Fee of 4.00 USD
|
@@ -0,0 +1,49 @@
|
|
1
|
+
:20:T099999996000001
|
2
|
+
:25:55555555/8888888888888
|
3
|
+
:28C:00004/00001
|
4
|
+
:60F:D070903EUR1234718,36
|
5
|
+
:61:0709040904CR300,NTRFTFNr 40005 MSGID//0724710345313905
|
6
|
+
:86:159?00RETOURE?100399?20EREF+TFNR 40005 00005?21MTLG:Grund nicht s
|
7
|
+
pezifizie?22rt Reject aus SEPA-Ueberwei?23sungsauftrag?34914
|
8
|
+
:61:0709040904CR335,33NTRFTFNr 44003 MSGID//0724710351061491
|
9
|
+
:86:159?00RETOURE?100399?20EREF+TFNR 44003 00001?21MTLG:Grund nicht s
|
10
|
+
pezifizie?22rt Reject aus SEPA-Ueberwei?23sungsauftrag?34914
|
11
|
+
:61:0709040904CR15000,NTRFTFNr 40005 MSGID//0724710345313900
|
12
|
+
:86:159?00RETOURE?100399?20EREF+TFNR 40005 00002?21MTLG:Grund nicht s
|
13
|
+
pezifizie?22rt Reject aus SEPA-Ueberwei?23sungsauftrag?34914
|
14
|
+
:61:0709040904CR66295,08NMSCNONREF
|
15
|
+
:86:079?00SAMMLER?109800?200904059001
|
16
|
+
:61:0709040904CR915311,55NTRFTFNr 44003 MSGID//R724710351061495
|
17
|
+
:86:159?00RETOURE?100399?20EREF+TFNR 44003 00002?21MTLG:Konto gesperr
|
18
|
+
t Rueckue?22berweisung aus SEPA-Ueberwe?23isungsauftrag?34903
|
19
|
+
:61:0709040904RCR204,88NRTINONREF
|
20
|
+
:86:079?00SAMMLER/STORNO?109800?200904059003
|
21
|
+
:61:0709040904DR999946,95NMSCNONREF
|
22
|
+
:86:079?00SAMMLER?109800?200904059002
|
23
|
+
:62F:D070904EUR1237628,23
|
24
|
+
:64:D070904EUR1237628,23
|
25
|
+
-
|
26
|
+
:20:T099999996000001
|
27
|
+
:25:55555555/8888888888889
|
28
|
+
:28C:00004/00001
|
29
|
+
:60F:D070903EUR1234718,36
|
30
|
+
:61:0709040904CR300,NTRFTFNr 40005 MSGID//0724710345313905
|
31
|
+
:86:159?00RETOURE?100399?20EREF+TFNR 40005 00005?21MTLG:Grund nicht s
|
32
|
+
pezifizie?22rt Reject aus SEPA-Ueberwei?23sungsauftrag?34914
|
33
|
+
:61:0709040904CR335,33NTRFTFNr 44003 MSGID//0724710351061491
|
34
|
+
:86:159?00RETOURE?100399?20EREF+TFNR 44003 00001?21MTLG:Grund nicht s
|
35
|
+
pezifizie?22rt Reject aus SEPA-Ueberwei?23sungsauftrag?34914
|
36
|
+
:61:0709040904CR15000,NTRFTFNr 40005 MSGID//0724710345313900
|
37
|
+
:86:159?00RETOURE?100399?20EREF+TFNR 40005 00002?21MTLG:Grund nicht s
|
38
|
+
pezifizie?22rt Reject aus SEPA-Ueberwei?23sungsauftrag?34914
|
39
|
+
:61:0709040904CR66295,08NMSCNONREF
|
40
|
+
:86:079?00SAMMLER?109800?200904059001
|
41
|
+
:61:0709040904CR915311,55NTRFTFNr 44003 MSGID//R724710351061495
|
42
|
+
:86:159?00RETOURE?100399?20EREF+TFNR 44003 00002?21MTLG:Konto gesperr
|
43
|
+
t Rueckue?22berweisung aus SEPA-Ueberwe?23isungsauftrag?34903
|
44
|
+
:61:0709040904RCR204,88NRTINONREF
|
45
|
+
:86:079?00SAMMLER/STORNO?109800?200904059003
|
46
|
+
:61:0709040904DR999946,95NMSCNONREF
|
47
|
+
:86:079?00SAMMLER?109800?200904059002
|
48
|
+
:62F:D070904EUR1237628,23
|
49
|
+
:64:D070904EUR1237628,23
|
@@ -0,0 +1,16 @@
|
|
1
|
+
:20:T089413946000001
|
2
|
+
:25:50880050/0194774600888
|
3
|
+
-
|
4
|
+
:20:T089413966000001
|
5
|
+
:25:50880050/0194778300888
|
6
|
+
|
7
|
+
:61:0709040904CR125,88NTRFNONREF//0724710290635078
|
8
|
+
:86:166?00GUTSCHRIFT?100399?20EREF+EndToEndIdTFNR52001000?2101?22SVWZ
|
9
|
+
+Keine Buchung zu: TO13?23 TF52001 MINT?30PBNKDEFF100?31DE4210010
|
10
|
+
0100043921105?32Richter Renate 70 Zeichen B?33eginn Fuellzeichen
|
11
|
+
xxxxxxxx?70Dora Damm 70 Zeichen Beginn?71 Fuellzeichen xxxxxxxxxx
|
12
|
+
xxx
|
13
|
+
-
|
14
|
+
:20:T089413976000001
|
15
|
+
:25:50880050/0194779500888
|
16
|
+
-
|
@@ -0,0 +1,27 @@
|
|
1
|
+
:20:STAR1ÜTßUMS
|
2
|
+
:25:51230800/0000007055
|
3
|
+
:28C:00027/00001
|
4
|
+
:60F:C100318EUR380115,77
|
5
|
+
:61:1003190319CR27,00NTRF100323-03-100323//32-P1-TCS49518
|
6
|
+
:86:051?00Bank Transfer Credit?10930226?20QQW53T2245ZGY46J ABBUCH
|
7
|
+
UNG?21VOM PAYPAL-KONTO?22100318P3TX1433EV?3050070010?310175526300
|
8
|
+
?32PAYPAL?34000
|
9
|
+
:61:1003190319CR13068,30N051NONREF
|
10
|
+
:86:051?00Bank Transfer Credit?10991118?20BETTERPLACE WDB E?2108.
|
11
|
+
03.10-14.03.10?3051230800?319990437808?32WIRECARD BANK AG?34000
|
12
|
+
:61:1003190319DR193282,05N035NONREF
|
13
|
+
:86:035?00Zahlung m.Elektr.Unterschr.?10991132?20Belegloser Zahlu
|
14
|
+
ngsauftrag?21Erstellungsdatum:19.03.2010?22Anzahl Posten : 9
|
15
|
+
4?23Anw-Nr.: 69725563000?34540
|
16
|
+
:62F:C100319EUR199929,02
|
17
|
+
-
|
18
|
+
:20:STAR1ÜTUMS
|
19
|
+
:25:51230800/0000007304
|
20
|
+
:28C:00053/00001
|
21
|
+
:60F:C100318EUR130073,19
|
22
|
+
:61:1003220319CR1120,00N085NONREF
|
23
|
+
:86:085?00Zahlung m.Elektr.Unterschr.?10991135?20Belegloser Zahlu
|
24
|
+
ngsauftrag?21Überweisung:19.03.2010?22Anzahl Posten :
|
25
|
+
7?23Anw-Nr.: 69725663086?34540
|
26
|
+
:62F:C100319EUR131193,19
|
27
|
+
-
|
@@ -0,0 +1,118 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe SaltParser::Swift::Builder do
|
4
|
+
context "parsing" do
|
5
|
+
it "parses text file with data in mt940(SWIFT) format with barclays bank export" do
|
6
|
+
parser = SaltParser::Swift::Builder.new("spec/swift/fixtures/barclays.txt").parser
|
7
|
+
parser.accounts.size.should == 1
|
8
|
+
parser.accounts.first.to_hash.except(:transactions).should == {
|
9
|
+
:account_identification => "USD:555:7777777",
|
10
|
+
:closing_balance => {
|
11
|
+
:balance_type => :start,
|
12
|
+
:sign => :credit,
|
13
|
+
:currency => "USD",
|
14
|
+
:amount => 3011433,
|
15
|
+
:date => Date.new(2012,4,24)
|
16
|
+
}
|
17
|
+
}
|
18
|
+
parser.accounts.first.transactions.size.should == 11
|
19
|
+
parser.accounts.first.transactions.first.to_hash.should == {
|
20
|
+
:date => Date.new(2012,1,25),
|
21
|
+
:entry_date => Date.new(2012,1,25),
|
22
|
+
:funds_code => :debit,
|
23
|
+
:amount => 2500,
|
24
|
+
:swift_code => "FTRF",
|
25
|
+
:reference => "SUB FEE BI//0",
|
26
|
+
:transaction_description => "",
|
27
|
+
:info => nil
|
28
|
+
}
|
29
|
+
end
|
30
|
+
|
31
|
+
it "parses text file with data in mt940 format (SWIFT)" do
|
32
|
+
parser = SaltParser::Swift::Builder.new("spec/swift/fixtures/sepa_mt9401.txt").parser
|
33
|
+
parser.accounts.size.should == 2
|
34
|
+
|
35
|
+
parser.accounts.first.to_hash.except(:transactions).should == {
|
36
|
+
:account_identification => "55555555/8888888888888",
|
37
|
+
:closing_balance => {
|
38
|
+
:balance_type => :start,
|
39
|
+
:sign => :debit,
|
40
|
+
:currency => "EUR",
|
41
|
+
:amount => 123762823,
|
42
|
+
:date => Date.new(2007,9,4)
|
43
|
+
}
|
44
|
+
}
|
45
|
+
parser.accounts.map(&:transactions).flatten.size.should == 14
|
46
|
+
parser.accounts.first.transactions.first.to_hash.should == {
|
47
|
+
:date => Date.new(2007,9,4),
|
48
|
+
:entry_date => Date.new(2007,9,4),
|
49
|
+
:funds_code => :credit,
|
50
|
+
:amount => 300,
|
51
|
+
:swift_code => "NTRF",
|
52
|
+
:reference => "TFNr 40005 MSGID",
|
53
|
+
:transaction_description => "0724710345313905",
|
54
|
+
:info =>
|
55
|
+
{
|
56
|
+
:code => 159,
|
57
|
+
:transaction_description => "RETOURE",
|
58
|
+
:prima_nota => "0399",
|
59
|
+
:details => "EREF+TFNR 40005 00005\nMTLG:Grund nicht spezifizie\nrt Reject aus SEPA-Ueberwei\nsungsauftrag",
|
60
|
+
:bank_code => nil,
|
61
|
+
:account_number => nil,
|
62
|
+
:account_holder => "",
|
63
|
+
:text_key_extension => "914",
|
64
|
+
:not_implemented_fields => nil
|
65
|
+
}
|
66
|
+
}
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
context "initialize" do
|
71
|
+
it "should initialize with file path" do
|
72
|
+
parser = SaltParser::Swift::Builder.new("spec/swift/fixtures/test.txt").parser
|
73
|
+
parser.accounts.size.should == 3
|
74
|
+
end
|
75
|
+
|
76
|
+
it "should initialize with an IO object" do
|
77
|
+
parser = SaltParser::Swift::Builder.new(open("spec/swift/fixtures/test.txt")).parser
|
78
|
+
parser.accounts.size.should == 3
|
79
|
+
end
|
80
|
+
|
81
|
+
it "should initialize with data in a string" do
|
82
|
+
parser = SaltParser::Swift::Builder.new(File.read("spec/swift/fixtures/test.txt")).parser
|
83
|
+
parser.accounts.size.should == 3
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
context "exceptional situations" do
|
88
|
+
it "does not fail if file has empty line" do
|
89
|
+
expect { SaltParser::Swift::Builder.new("spec/swift/fixtures/empty_line.txt").parser }.to_not raise_error
|
90
|
+
end
|
91
|
+
|
92
|
+
it "raise error if have unknown data" do
|
93
|
+
parser = SaltParser::Swift::Builder.new("spec/swift/fixtures/unknown_data.txt").parser
|
94
|
+
expect { parser }.to_not raise_error
|
95
|
+
|
96
|
+
parser.errors.size.should == 1
|
97
|
+
end
|
98
|
+
|
99
|
+
it "should not fail if :86: tag has no :61: predecessor" do
|
100
|
+
parser = SaltParser::Swift::Builder.new("spec/swift/fixtures/empty_86.txt").parser
|
101
|
+
parser.accounts.first.transactions.should be_empty
|
102
|
+
end
|
103
|
+
|
104
|
+
it "does not fail if file has unusual characters" do
|
105
|
+
parser = SaltParser::Swift::Builder.new("spec/swift/fixtures/with_binary_character.txt").parser
|
106
|
+
parser.accounts.size.should == 2
|
107
|
+
parser.accounts.last.transactions.last.info.details
|
108
|
+
.should == "Belegloser Zahlungsauftrag\nÜberweisung:19.03.2010\nAnzahl Posten :7\nAnw-Nr.: 69725663086"
|
109
|
+
end
|
110
|
+
|
111
|
+
it "should reject the file with wrong encoding" do
|
112
|
+
Kconv.should_receive(:isutf8).and_raise(StandardError)
|
113
|
+
expect do
|
114
|
+
SaltParser::Swift::Builder.new("spec/swift/fixtures/test.txt").parser
|
115
|
+
end.to raise_error(SaltParser::Error::InvalidEncoding)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: salt-parser
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- saltedge team
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-11-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: nokogiri
|
@@ -80,7 +80,7 @@ dependencies:
|
|
80
80
|
- - ">="
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0'
|
83
|
-
description: Gem for parsing OFX,
|
83
|
+
description: Gem for parsing OFX, QIF and SWIFT formats.
|
84
84
|
email:
|
85
85
|
- support@saltedge.com
|
86
86
|
executables: []
|
@@ -91,7 +91,7 @@ files:
|
|
91
91
|
- ".rspec"
|
92
92
|
- Gemfile
|
93
93
|
- Gemfile.lock
|
94
|
-
- README.
|
94
|
+
- README.md
|
95
95
|
- Rakefile
|
96
96
|
- lib/ofx/account.rb
|
97
97
|
- lib/ofx/accounts.rb
|
@@ -114,6 +114,14 @@ files:
|
|
114
114
|
- lib/salt-parser/builder.rb
|
115
115
|
- lib/salt-parser/errors.rb
|
116
116
|
- lib/salt-parser/version.rb
|
117
|
+
- lib/swift/account.rb
|
118
|
+
- lib/swift/accounts.rb
|
119
|
+
- lib/swift/builder.rb
|
120
|
+
- lib/swift/dependencies.rb
|
121
|
+
- lib/swift/parser.rb
|
122
|
+
- lib/swift/supported_fields.rb
|
123
|
+
- lib/swift/transaction.rb
|
124
|
+
- lib/swift/transaction_info.rb
|
117
125
|
- salt-parser.gemspec
|
118
126
|
- spec/ofx/account_spec.rb
|
119
127
|
- spec/ofx/accounts_response_spec.rb
|
@@ -182,10 +190,19 @@ files:
|
|
182
190
|
- spec/qif/transaction_spec.rb
|
183
191
|
- spec/spec_helper.rb
|
184
192
|
- spec/support/fixture.rb
|
193
|
+
- spec/swift/fixtures/barclays.txt
|
194
|
+
- spec/swift/fixtures/empty_86.txt
|
195
|
+
- spec/swift/fixtures/empty_line.txt
|
196
|
+
- spec/swift/fixtures/sepa_mt9401.txt
|
197
|
+
- spec/swift/fixtures/test.txt
|
198
|
+
- spec/swift/fixtures/unknown_data.txt
|
199
|
+
- spec/swift/fixtures/with_binary_character.txt
|
200
|
+
- spec/swift/parser_spec.rb
|
185
201
|
homepage: http://saltedge.com
|
186
202
|
licenses:
|
187
203
|
- MIT
|
188
|
-
metadata:
|
204
|
+
metadata:
|
205
|
+
issue_tracker: https://github.com/saltedge/salt-parser/issues
|
189
206
|
post_install_message:
|
190
207
|
rdoc_options: []
|
191
208
|
require_paths:
|
@@ -205,5 +222,5 @@ rubyforge_project:
|
|
205
222
|
rubygems_version: 2.4.6
|
206
223
|
signing_key:
|
207
224
|
specification_version: 4
|
208
|
-
summary: Gem for parsing OFX,
|
225
|
+
summary: Gem for parsing OFX, QIF and SWIFT formats.
|
209
226
|
test_files: []
|