camt_parser 1.0.2 → 1.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/lib/camt_parser/052/base.rb +15 -0
- data/lib/camt_parser/052/report.rb +58 -0
- data/lib/camt_parser/053/base.rb +1 -1
- data/lib/camt_parser/053/statement.rb +47 -55
- data/lib/camt_parser/errors.rb +6 -0
- data/lib/camt_parser/file.rb +2 -11
- data/lib/camt_parser/general/account.rb +19 -0
- data/lib/camt_parser/general/account_balance.rb +43 -0
- data/lib/camt_parser/general/creditor.rb +23 -0
- data/lib/camt_parser/general/debitor.rb +23 -0
- data/lib/camt_parser/general/entry.rb +111 -0
- data/lib/camt_parser/general/group_header.rb +27 -0
- data/lib/camt_parser/misc.rb +13 -0
- data/lib/camt_parser/string.rb +19 -0
- data/lib/camt_parser/version.rb +1 -1
- data/lib/camt_parser.rb +18 -6
- metadata +18 -8
- data/lib/camt_parser/053/group_header.rb +0 -29
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 89b432e8beb46ea683a5d897d11a3e3f7a923c6b
|
|
4
|
+
data.tar.gz: c90fca06cf5c7c2758ff54de9b5621e4caefc561
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 1975140e3c8293086a96811e6c63f0e2cfb32169866391ab0191cc96d0c71fecb5e66f35796830f481e43e8788dc0d85088b9e2c9a410d26ccbb7cd1415e2273
|
|
7
|
+
data.tar.gz: 6c9d7648926d601d6afb9982b9fb28a6f5af9b46c6f53139a8f1d4d00ad7c368c78ff76762a7244e84330e9230228d4814e9c45b72261644607b7161649cf5d1
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
module CamtParser
|
|
2
|
+
module Format052
|
|
3
|
+
class Base
|
|
4
|
+
attr_reader :group_header, :reports
|
|
5
|
+
|
|
6
|
+
def initialize(xml_data)
|
|
7
|
+
# BkToCstmrAccptRpt = Bank to Customer Account Report
|
|
8
|
+
grphdr = xml_data.xpath('BkToCstmrAcctRpt/GrpHdr')
|
|
9
|
+
@group_header = CamtParser::GroupHeader.new(grphdr)
|
|
10
|
+
reports = xml_data.xpath('BkToCstmrAcctRpt/Rpt')
|
|
11
|
+
@reports = reports.map{ |x| Report.new(x) }
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
module CamtParser
|
|
2
|
+
module Format052
|
|
3
|
+
class Report
|
|
4
|
+
def initialize(xml_data)
|
|
5
|
+
@xml_data = xml_data
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def identification
|
|
9
|
+
@identification ||= @xml_data.xpath('Id/text()').text
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def generation_date
|
|
13
|
+
@generation_date ||= Time.parse(@xml_data.xpath('CreDtTm/text()').text)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def account
|
|
17
|
+
@account ||= CamtParser::Account.new(@xml_data.xpath('Acct').first)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def entries
|
|
21
|
+
@entries ||= @xml_data.xpath('Ntry').map{ |x| CamtParser::Entry.new(x) }
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def legal_sequence_number
|
|
25
|
+
@legal_sequence_number ||= @xml_data.xpath('LglSeqNb/text()').text
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def opening_balance
|
|
29
|
+
@opening_balance ||= begin
|
|
30
|
+
bal = @xml_data.xpath('Bal/Tp//Cd[contains(text(), "PRCD")]').first.ancestors('Bal')
|
|
31
|
+
date = bal.xpath('Dt/Dt/text()').text
|
|
32
|
+
currency = bal.xpath('Amt').attribute('Ccy').value
|
|
33
|
+
CamtParser::AccountBalance.new bal.xpath('Amt/text()').text, currency, date, true
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
alias_method :opening_or_intermediary_balance, :opening_balance
|
|
37
|
+
|
|
38
|
+
def closing_balance
|
|
39
|
+
@closing_balance ||= begin
|
|
40
|
+
bal = @xml_data.xpath('Bal/Tp//Cd[contains(text(), "CLBD")]').first.ancestors('Bal')
|
|
41
|
+
date = bal.xpath('Dt/Dt/text()').text
|
|
42
|
+
currency = bal.xpath('Amt').attribute('Ccy').value
|
|
43
|
+
CamtParser::AccountBalance.new bal.xpath('Amt/text()').text, currency, date, true
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
alias_method :closing_or_intermediary_balance, :closing_balance
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def source
|
|
50
|
+
@xml_data.to_s
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def self.parse(xml)
|
|
54
|
+
self.new Nokogiri::XML(xml).xpath('Report')
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
data/lib/camt_parser/053/base.rb
CHANGED
|
@@ -7,7 +7,7 @@ module CamtParser
|
|
|
7
7
|
grphdr = xml_data.xpath('BkToCstmrStmt/GrpHdr')
|
|
8
8
|
@group_header = GroupHeader.new(grphdr)
|
|
9
9
|
statements = xml_data.xpath('BkToCstmrStmt/Stmt')
|
|
10
|
-
@statements
|
|
10
|
+
@statements = statements.map{ |x| Statement.new(x) }
|
|
11
11
|
end
|
|
12
12
|
end
|
|
13
13
|
end
|
|
@@ -1,76 +1,68 @@
|
|
|
1
|
-
require 'time'
|
|
2
|
-
require 'bigdecimal'
|
|
3
|
-
|
|
4
1
|
module CamtParser
|
|
5
2
|
module Format053
|
|
6
3
|
class Statement
|
|
7
|
-
attr_reader :identification, :creation_date_time, :from_date_time, :to_date_time,
|
|
8
|
-
:account, :entries
|
|
9
|
-
|
|
10
4
|
def initialize(xml_data)
|
|
11
|
-
@
|
|
12
|
-
@creation_date_time = Time.parse(xml_data.xpath('CreDtTm').first.content)
|
|
13
|
-
@from_date_time = (x = xml_data.xpath('FrToDt/FrDtTm')).empty? ? nil : Time.parse(x.first.content)
|
|
14
|
-
@to_date_time = (x = xml_data.xpath('FrToDt/ToDtTm')).empty? ? nil : Time.parse(x.first.content)
|
|
15
|
-
@account = Account.new(xml_data.xpath('Acct').first)
|
|
16
|
-
@entries = xml_data.xpath('Ntry').map{ |x| Entry.new(x) }
|
|
5
|
+
@xml_data = xml_data
|
|
17
6
|
end
|
|
18
|
-
end
|
|
19
7
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
8
|
+
def identification
|
|
9
|
+
@identification ||= @xml_data.xpath('Id/text()').text
|
|
10
|
+
end
|
|
23
11
|
|
|
24
|
-
def
|
|
25
|
-
@
|
|
26
|
-
@currency = xml_data.xpath('Amt/@Ccy').first.content
|
|
27
|
-
@debit = xml_data.xpath('CdtDbtInd').first.content.upcase == 'DBIT'
|
|
28
|
-
@value_date = Date.parse(xml_data.xpath('ValDt/Dt').first.content)
|
|
29
|
-
@creditor = Creditor.new(xml_data.xpath('NtryDtls'))
|
|
30
|
-
@debitor = Debitor.new(xml_data.xpath('NtryDtls'))
|
|
31
|
-
@additional_information = xml_data.xpath('AddtlNtryInf').first.content
|
|
32
|
-
# Makes the assumption that only unstructured remittance information will be given
|
|
33
|
-
if (x = xml_data.xpath('NtryDtls/TxDtls/RmtInf/Ustrd')).empty?
|
|
34
|
-
@remittance_information = nil
|
|
35
|
-
else
|
|
36
|
-
@remittance_information = x.collect(&:content).join(' ')
|
|
37
|
-
end
|
|
12
|
+
def generation_date
|
|
13
|
+
@generation_date ||= Time.parse(@xml_data.xpath('CreDtTm/text()').text)
|
|
38
14
|
end
|
|
39
15
|
|
|
40
|
-
def
|
|
41
|
-
@
|
|
16
|
+
def from_date_time
|
|
17
|
+
@from_date_time ||= (x = @xml_data.xpath('FrToDt/FrDtTm')).empty? ? nil : Time.parse(x.first.content)
|
|
42
18
|
end
|
|
43
|
-
end
|
|
44
19
|
|
|
45
|
-
|
|
46
|
-
|
|
20
|
+
def to_date_time
|
|
21
|
+
@to_date_time ||= (x = @xml_data.xpath('FrToDt/ToDtTm')).empty? ? nil : Time.parse(x.first.content)
|
|
22
|
+
end
|
|
47
23
|
|
|
48
|
-
def
|
|
49
|
-
@
|
|
50
|
-
@bic = (x = xml_data.xpath('Svcr/FinInstnId/BIC')).empty? ? nil : x.first.content
|
|
51
|
-
@bank_name = (x = xml_data.xpath('Svcr/FinInstnId/Nm')).empty? ? nil : x.first.content
|
|
24
|
+
def account
|
|
25
|
+
@account ||= Account.new(@xml_data.xpath('Acct').first)
|
|
52
26
|
end
|
|
53
|
-
end
|
|
54
27
|
|
|
55
|
-
|
|
56
|
-
|
|
28
|
+
def entries
|
|
29
|
+
@entries ||= @xml_data.xpath('Ntry').map{ |x| Entry.new(x) }
|
|
30
|
+
end
|
|
57
31
|
|
|
58
|
-
def
|
|
59
|
-
@
|
|
60
|
-
@iban = (x = xml_data.xpath('TxDtls/RltdPties/DbtrAcct/Id/IBAN')).empty? ? nil : x.first.content
|
|
61
|
-
@bic = (x = xml_data.xpath('TxDtls/RltdAgts/DbtrAgt/FinInstnId/BIC')).empty? ? nil : x.first.content
|
|
62
|
-
@bank_name = (x = xml_data.xpath('TxDtls/RltdAgts/DbtrAgt/FinInstnId/Nm')).empty? ? nil : x.first.content
|
|
32
|
+
def legal_sequence_number
|
|
33
|
+
@legal_sequence_number ||= @xml_data.xpath('LglSeqNb/text()').text
|
|
63
34
|
end
|
|
64
|
-
end
|
|
65
35
|
|
|
66
|
-
|
|
67
|
-
|
|
36
|
+
def electronic_sequence_number
|
|
37
|
+
@electronic_sequence_number ||= @xml_data.xpath('ElctrncSeqNb/text()').text
|
|
38
|
+
end
|
|
68
39
|
|
|
69
|
-
def
|
|
70
|
-
@
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
40
|
+
def opening_balance
|
|
41
|
+
@opening_balance ||= begin
|
|
42
|
+
bal = @xml_data.xpath('Bal/Tp//Cd[contains(text(), "PRCD")]').first.ancestors('Bal')
|
|
43
|
+
date = bal.xpath('Dt/Dt/text()').text
|
|
44
|
+
currency = bal.xpath('Amt').attribute('Ccy').value
|
|
45
|
+
AccountBalance.new bal.xpath('Amt/text()').text, currency, date, true
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
alias_method :opening_or_intermediary_balance, :opening_balance
|
|
49
|
+
|
|
50
|
+
def closing_balance
|
|
51
|
+
@closing_balance ||= begin
|
|
52
|
+
bal = @xml_data.xpath('Bal/Tp//Cd[contains(text(), "CLBD")]').first.ancestors('Bal')
|
|
53
|
+
date = bal.xpath('Dt/Dt/text()').text
|
|
54
|
+
currency = bal.xpath('Amt').attribute('Ccy').value
|
|
55
|
+
AccountBalance.new bal.xpath('Amt/text()').text, currency, date, true
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
alias_method :closing_or_intermediary_balance, :closing_balance
|
|
59
|
+
|
|
60
|
+
def source
|
|
61
|
+
@xml_data.to_s
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def self.parse(xml)
|
|
65
|
+
self.new Nokogiri::XML(xml).xpath('Stmt')
|
|
74
66
|
end
|
|
75
67
|
end
|
|
76
68
|
end
|
data/lib/camt_parser/file.rb
CHANGED
|
@@ -1,17 +1,8 @@
|
|
|
1
1
|
module CamtParser
|
|
2
2
|
class File
|
|
3
3
|
def self.parse(path)
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
f.close
|
|
7
|
-
|
|
8
|
-
case doc.namespaces["xmlns"]
|
|
9
|
-
when "urn:iso:std:iso:20022:tech:xsd:camt.053.001.02"
|
|
10
|
-
doc.remove_namespaces!
|
|
11
|
-
return CamtParser::Format053::Base.new(doc.xpath("Document"))
|
|
12
|
-
else
|
|
13
|
-
raise "unknown or unsupported namespace: #{doc.namespaces["xlmns"]}"
|
|
14
|
-
end
|
|
4
|
+
data = ::File.read(path)
|
|
5
|
+
CamtParser::String.parse(data)
|
|
15
6
|
end
|
|
16
7
|
end
|
|
17
8
|
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
module CamtParser
|
|
2
|
+
class Account
|
|
3
|
+
def initialize(xml_data)
|
|
4
|
+
@xml_data = xml_data
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def iban
|
|
8
|
+
@iban ||= @xml_data.xpath('Id/IBAN/text()').text
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def bic
|
|
12
|
+
@bic ||= @xml_data.xpath('Svcr/FinInstnId/BIC/text()').text
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def bank_name
|
|
16
|
+
@bank_name ||= @xml_data.xpath('Svcr/FinInstnId/Nm/text()').text
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
module CamtParser
|
|
2
|
+
class AccountBalance
|
|
3
|
+
|
|
4
|
+
def initialize(amount, currency, date, credit = false)
|
|
5
|
+
@amount = amount
|
|
6
|
+
@currency = currency
|
|
7
|
+
@date = date
|
|
8
|
+
@credit = credit
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def currency
|
|
12
|
+
@currency
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def date
|
|
16
|
+
Date.parse @date
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def sign
|
|
20
|
+
credit? ? 1 : -1
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def credit?
|
|
24
|
+
@credit
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def amount
|
|
28
|
+
CamtParser::Misc.to_amount(@amount)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def amount_in_cents
|
|
32
|
+
CamtParser::Misc.to_amount_in_cents(@amount)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def to_h
|
|
36
|
+
{
|
|
37
|
+
'amount' => amount,
|
|
38
|
+
'amount_in_cents' => amount_in_cents,
|
|
39
|
+
'sign' => sign
|
|
40
|
+
}
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
module CamtParser
|
|
2
|
+
class Creditor
|
|
3
|
+
def initialize(xml_data)
|
|
4
|
+
@xml_data = xml_data
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def name
|
|
8
|
+
@name ||= @xml_data.xpath('TxDtls/RltdPties/Cdtr/Nm/text()').text
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def iban
|
|
12
|
+
@iban ||= @xml_data.xpath('TxDtls/RltdPties/CdtrAcct/Id/IBAN/text()').text
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def bic
|
|
16
|
+
@bic ||= @xml_data.xpath('TxDtls/RltdAgts/CdtrAgt/FinInstnId/BIC/text()').text
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def bank_name
|
|
20
|
+
@bank_name ||= @xml_data.xpath('TxDtls/RltdAgts/CdtrAgt/FinInstnId/Nm/text()').text
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
module CamtParser
|
|
2
|
+
class Debitor
|
|
3
|
+
def initialize(xml_data)
|
|
4
|
+
@xml_data = xml_data
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def name
|
|
8
|
+
@name ||= @xml_data.xpath('TxDtls/RltdPties/Dbtr/Nm/text()').text
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def iban
|
|
12
|
+
@iban ||= @xml_data.xpath('TxDtls/RltdPties/DbtrAcct/Id/IBAN/text()').text
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def bic
|
|
16
|
+
@bic ||= @xml_data.xpath('TxDtls/RltdAgts/DbtrAgt/FinInstnId/BIC/text()').text
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def bank_name
|
|
20
|
+
@bank_name ||= @xml_data.xpath('TxDtls/RltdAgts/DbtrAgt/FinInstnId/Nm/text()').text
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
module CamtParser
|
|
2
|
+
class Entry
|
|
3
|
+
def initialize(xml_data)
|
|
4
|
+
@xml_data = xml_data
|
|
5
|
+
@amount = @xml_data.xpath('Amt/text()').text
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def amount
|
|
9
|
+
CamtParser::Misc.to_amount(@amount)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def amount_in_cents
|
|
13
|
+
CamtParser::Misc.to_amount_in_cents(@amount)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def currency
|
|
17
|
+
@currency ||= @xml_data.xpath('Amt/@Ccy').text
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def debit
|
|
21
|
+
@debit ||= @xml_data.xpath('CdtDbtInd/text()').text.upcase == 'DBIT'
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def value_date
|
|
25
|
+
@value_date ||= Date.parse(@xml_data.xpath('ValDt/Dt/text()').text)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def booking_date
|
|
29
|
+
@booking_date ||= Date.parse(@xml_data.xpath('BookgDt/Dt/text()').text)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def creditor
|
|
33
|
+
@creditor ||= CamtParser::Creditor.new(@xml_data.xpath('NtryDtls'))
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def credit?
|
|
37
|
+
!debit
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def debitor
|
|
41
|
+
@debitor ||= CamtParser::Debitor.new(@xml_data.xpath('NtryDtls'))
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def debit?
|
|
45
|
+
debit
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def sign
|
|
49
|
+
credit? ? 1 : -1
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def additional_information
|
|
53
|
+
@additional_information ||= @xml_data.xpath('AddtlNtryInf/text()').text
|
|
54
|
+
end
|
|
55
|
+
alias_method :description, :additional_information
|
|
56
|
+
|
|
57
|
+
def remittance_information
|
|
58
|
+
@remittance_information ||= begin
|
|
59
|
+
if (x = @xml_data.xpath('NtryDtls/TxDtls/RmtInf/Ustrd')).empty?
|
|
60
|
+
nil
|
|
61
|
+
else
|
|
62
|
+
x.collect(&:content).join(' ')
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def name
|
|
68
|
+
credit? ? debitor.name : creditor.name
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def iban
|
|
72
|
+
credit? ? debitor.iban : creditor.iban
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def bic
|
|
76
|
+
credit? ? debitor.bic : creditor.bic
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def swift_code
|
|
80
|
+
@swift_code ||= @xml_data.xpath('NtryDtls/TxDtls/BkTxCd/Prtry/Cd/text()').text.split('+')[0]
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def reference
|
|
84
|
+
@reference ||= @xml_data.xpath('NtryDtls/TxDtls/Refs/InstrId/text()').text
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def bank_reference # May be missing
|
|
88
|
+
@bank_reference ||= @xml_data.xpath('NtryDtls/TxDtls/Refs/AcctSvcrRef/text()').text
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def end_to_end_reference # May be missing
|
|
92
|
+
@end_to_end_reference ||= @xml_data.xpath('NtryDtls/TxDtls/Refs/EndToEndId/text()').text
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def mandate_reference # May be missing
|
|
96
|
+
@mandate_reference ||= @xml_data.xpath('NtryDtls/TxDtls/Refs/MndtId/text()').text
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def transaction_id # May be missing
|
|
100
|
+
@transaction_id ||= @xml_data.xpath('NtryDtls/TxDtls/Refs/TxId/text()').text
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def creditor_identifier # May be missing
|
|
104
|
+
@creditor_identifier ||= @xml_data.xpath('NtryDtls/TxDtls/RltdPties/Cdtr/Id/PrvtId/Othr/Id/text()').text
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def payment_information # May be missing
|
|
108
|
+
@payment_information ||= @xml_data.xpath('NtryDtls/TxDtls/Refs/PmtInfId/text()').text
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
require 'time'
|
|
2
|
+
|
|
3
|
+
module CamtParser
|
|
4
|
+
class GroupHeader
|
|
5
|
+
attr_reader :message_id, :creation_date_time, :additional_information, :message_pagination
|
|
6
|
+
|
|
7
|
+
def initialize(xml_data)
|
|
8
|
+
@message_id = xml_data.xpath('MsgId/text()').text
|
|
9
|
+
@creation_date_time = Time.parse(xml_data.xpath('CreDtTm/text()').text)
|
|
10
|
+
@message_pagination = (x = xml_data.xpath('MsgPgntn')).empty? ? nil : MessagePagination.new(x)
|
|
11
|
+
@additional_information = xml_data.xpath('AddtlInf/text()').text
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
class MessagePagination
|
|
16
|
+
attr_reader :page_number
|
|
17
|
+
|
|
18
|
+
def initialize(xml_data)
|
|
19
|
+
@page_number = xml_data.xpath('PgNb/text()').text.to_i
|
|
20
|
+
@last_page_indicator = xml_data.xpath('LastPgInd/text()').text == 'true'
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def last_page?
|
|
24
|
+
@last_page_indicator
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
module CamtParser
|
|
2
|
+
class String
|
|
3
|
+
def self.parse(raw_camt)
|
|
4
|
+
doc = Nokogiri::XML raw_camt
|
|
5
|
+
|
|
6
|
+
namespaces = doc.namespaces['xmlns']
|
|
7
|
+
doc.remove_namespaces!
|
|
8
|
+
|
|
9
|
+
case namespaces
|
|
10
|
+
when 'urn:iso:std:iso:20022:tech:xsd:camt.052.001.02'
|
|
11
|
+
return CamtParser::Format052::Base.new(doc.xpath('Document'))
|
|
12
|
+
when 'urn:iso:std:iso:20022:tech:xsd:camt.053.001.02'
|
|
13
|
+
return CamtParser::Format053::Base.new(doc.xpath('Document'))
|
|
14
|
+
else
|
|
15
|
+
raise CamtParser::Errors::UnsupportedNamespaceError, namespaces
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
data/lib/camt_parser/version.rb
CHANGED
data/lib/camt_parser.rb
CHANGED
|
@@ -1,9 +1,21 @@
|
|
|
1
1
|
# encoding: utf-8
|
|
2
|
-
|
|
3
2
|
require "nokogiri"
|
|
4
3
|
|
|
5
|
-
require "
|
|
6
|
-
require "
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
4
|
+
require "time"
|
|
5
|
+
require "bigdecimal"
|
|
6
|
+
|
|
7
|
+
require_relative "camt_parser/misc"
|
|
8
|
+
require_relative "camt_parser/version"
|
|
9
|
+
require_relative "camt_parser/errors"
|
|
10
|
+
require_relative "camt_parser/general/account_balance"
|
|
11
|
+
require_relative "camt_parser/general/creditor"
|
|
12
|
+
require_relative "camt_parser/general/debitor"
|
|
13
|
+
require_relative "camt_parser/general/entry"
|
|
14
|
+
require_relative "camt_parser/general/account"
|
|
15
|
+
require_relative "camt_parser/general/group_header"
|
|
16
|
+
require_relative "camt_parser/052/report"
|
|
17
|
+
require_relative "camt_parser/052/base"
|
|
18
|
+
require_relative "camt_parser/053/statement"
|
|
19
|
+
require_relative "camt_parser/053/base"
|
|
20
|
+
require_relative "camt_parser/file"
|
|
21
|
+
require_relative "camt_parser/string"
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: camt_parser
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.0
|
|
4
|
+
version: 1.1.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Tobias Schoknecht
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2016-05-06 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rake
|
|
@@ -70,16 +70,16 @@ dependencies:
|
|
|
70
70
|
name: nokogiri
|
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
|
72
72
|
requirements:
|
|
73
|
-
- - "
|
|
73
|
+
- - ">="
|
|
74
74
|
- !ruby/object:Gem::Version
|
|
75
|
-
version:
|
|
75
|
+
version: '0'
|
|
76
76
|
type: :runtime
|
|
77
77
|
prerelease: false
|
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
|
79
79
|
requirements:
|
|
80
|
-
- - "
|
|
80
|
+
- - ">="
|
|
81
81
|
- !ruby/object:Gem::Version
|
|
82
|
-
version:
|
|
82
|
+
version: '0'
|
|
83
83
|
description: A parser for the Camt file format
|
|
84
84
|
email:
|
|
85
85
|
- tobias.schoknecht@barzahlen.de
|
|
@@ -88,10 +88,20 @@ extensions: []
|
|
|
88
88
|
extra_rdoc_files: []
|
|
89
89
|
files:
|
|
90
90
|
- lib/camt_parser.rb
|
|
91
|
+
- lib/camt_parser/052/base.rb
|
|
92
|
+
- lib/camt_parser/052/report.rb
|
|
91
93
|
- lib/camt_parser/053/base.rb
|
|
92
|
-
- lib/camt_parser/053/group_header.rb
|
|
93
94
|
- lib/camt_parser/053/statement.rb
|
|
95
|
+
- lib/camt_parser/errors.rb
|
|
94
96
|
- lib/camt_parser/file.rb
|
|
97
|
+
- lib/camt_parser/general/account.rb
|
|
98
|
+
- lib/camt_parser/general/account_balance.rb
|
|
99
|
+
- lib/camt_parser/general/creditor.rb
|
|
100
|
+
- lib/camt_parser/general/debitor.rb
|
|
101
|
+
- lib/camt_parser/general/entry.rb
|
|
102
|
+
- lib/camt_parser/general/group_header.rb
|
|
103
|
+
- lib/camt_parser/misc.rb
|
|
104
|
+
- lib/camt_parser/string.rb
|
|
95
105
|
- lib/camt_parser/version.rb
|
|
96
106
|
homepage: https://github.com/Barzahlen/camt_parser
|
|
97
107
|
licenses:
|
|
@@ -113,7 +123,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
113
123
|
version: '0'
|
|
114
124
|
requirements: []
|
|
115
125
|
rubyforge_project:
|
|
116
|
-
rubygems_version: 2.
|
|
126
|
+
rubygems_version: 2.2.2
|
|
117
127
|
signing_key:
|
|
118
128
|
specification_version: 4
|
|
119
129
|
summary: Gem for parsing camt files into a speaking object.
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
require 'time'
|
|
2
|
-
|
|
3
|
-
module CamtParser
|
|
4
|
-
module Format053
|
|
5
|
-
class GroupHeader
|
|
6
|
-
attr_reader :message_id, :creation_date_time, :additional_information, :message_pagination
|
|
7
|
-
|
|
8
|
-
def initialize(xml_data)
|
|
9
|
-
@message_id = xml_data.xpath('MsgId').first.content
|
|
10
|
-
@creation_date_time = Time.parse(xml_data.xpath('CreDtTm').first.content)
|
|
11
|
-
@message_pagination = (x = xml_data.xpath('MsgPgntn')).empty? ? nil : MessagePagination.new(x)
|
|
12
|
-
@additional_information = (x = xml_data.xpath('AddtlInf')).empty? ? nil : x.first.content
|
|
13
|
-
end
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
class MessagePagination
|
|
17
|
-
attr_reader :page_number
|
|
18
|
-
|
|
19
|
-
def initialize(xml_data)
|
|
20
|
-
@page_number = xml_data.xpath('PgNb').first.content.to_i
|
|
21
|
-
@last_page_indicator = xml_data.xpath('LastPgInd').first.content == 'true'
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
def last_page?
|
|
25
|
-
@last_page_indicator
|
|
26
|
-
end
|
|
27
|
-
end
|
|
28
|
-
end
|
|
29
|
-
end
|