sepa_file_parser 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 +7 -0
- data/lib/sepa_file_parser/camt052/base.rb +18 -0
- data/lib/sepa_file_parser/camt052/report.rb +73 -0
- data/lib/sepa_file_parser/camt053/base.rb +18 -0
- data/lib/sepa_file_parser/camt053/statement.rb +75 -0
- data/lib/sepa_file_parser/camt054/base.rb +18 -0
- data/lib/sepa_file_parser/camt054/notification.rb +54 -0
- data/lib/sepa_file_parser/errors.rb +12 -0
- data/lib/sepa_file_parser/file.rb +10 -0
- data/lib/sepa_file_parser/general/account.rb +66 -0
- data/lib/sepa_file_parser/general/account_balance.rb +61 -0
- data/lib/sepa_file_parser/general/batch_detail.rb +24 -0
- data/lib/sepa_file_parser/general/charges.rb +25 -0
- data/lib/sepa_file_parser/general/creditor.rb +46 -0
- data/lib/sepa_file_parser/general/debitor.rb +46 -0
- data/lib/sepa_file_parser/general/entry.rb +117 -0
- data/lib/sepa_file_parser/general/group_header.rb +38 -0
- data/lib/sepa_file_parser/general/pain_entry.rb +46 -0
- data/lib/sepa_file_parser/general/postal_address.rb +45 -0
- data/lib/sepa_file_parser/general/record.rb +49 -0
- data/lib/sepa_file_parser/general/transaction.rb +139 -0
- data/lib/sepa_file_parser/general/type/builder.rb +20 -0
- data/lib/sepa_file_parser/general/type/code.rb +13 -0
- data/lib/sepa_file_parser/general/type/proprietary.rb +13 -0
- data/lib/sepa_file_parser/misc.rb +28 -0
- data/lib/sepa_file_parser/pain001/base.rb +18 -0
- data/lib/sepa_file_parser/pain001/payment_information.rb +44 -0
- data/lib/sepa_file_parser/pain008/base.rb +18 -0
- data/lib/sepa_file_parser/pain008/payment_information.rb +44 -0
- data/lib/sepa_file_parser/register.rb +23 -0
- data/lib/sepa_file_parser/string.rb +10 -0
- data/lib/sepa_file_parser/version.rb +5 -0
- data/lib/sepa_file_parser/xml.rb +45 -0
- data/lib/sepa_file_parser.rb +38 -0
- metadata +160 -0
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'time'
|
4
|
+
|
5
|
+
module SepaFileParser
|
6
|
+
class GroupHeader
|
7
|
+
|
8
|
+
attr_reader :message_id,
|
9
|
+
:creation_date_time,
|
10
|
+
:additional_information,
|
11
|
+
:message_pagination,
|
12
|
+
:xml_data
|
13
|
+
|
14
|
+
def initialize(xml_data)
|
15
|
+
@xml_data = xml_data
|
16
|
+
@message_id = xml_data.xpath('MsgId/text()').text
|
17
|
+
@creation_date_time = Time.parse(xml_data.xpath('CreDtTm/text()').text)
|
18
|
+
@message_pagination = (x = xml_data.xpath('MsgPgntn')).empty? ? nil : MessagePagination.new(x)
|
19
|
+
@additional_information = xml_data.xpath('AddtlInf/text()').text
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
class MessagePagination
|
24
|
+
|
25
|
+
attr_reader :page_number,
|
26
|
+
:xml_data
|
27
|
+
|
28
|
+
def initialize(xml_data)
|
29
|
+
@xml_data = xml_data
|
30
|
+
@page_number = xml_data.xpath('PgNb/text()').text.to_i
|
31
|
+
@last_page_indicator = xml_data.xpath('LastPgInd/text()').text == 'true'
|
32
|
+
end
|
33
|
+
|
34
|
+
def last_page?
|
35
|
+
@last_page_indicator
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SepaFileParser
|
4
|
+
class PainEntry
|
5
|
+
|
6
|
+
attr_reader :xml_data
|
7
|
+
|
8
|
+
def initialize(xml_data)
|
9
|
+
@xml_data = xml_data
|
10
|
+
|
11
|
+
@amount = [
|
12
|
+
xml_data.xpath('Amt/InstdAmt').first,
|
13
|
+
xml_data.xpath('InstdAmt').first,
|
14
|
+
].find { |a| a != nil }.text
|
15
|
+
end
|
16
|
+
|
17
|
+
def amount
|
18
|
+
SepaFileParser::Misc.to_amount(@amount)
|
19
|
+
end
|
20
|
+
|
21
|
+
def amount_in_cents
|
22
|
+
SepaFileParser::Misc.to_amount_in_cents(@amount)
|
23
|
+
end
|
24
|
+
|
25
|
+
# @return [String]
|
26
|
+
def currency
|
27
|
+
@currency ||= [
|
28
|
+
xml_data.xpath('Amt/InstdAmt/@Ccy').first,
|
29
|
+
xml_data.xpath('InstdAmt/@Ccy').first,
|
30
|
+
].find { |a| a != nil }.text
|
31
|
+
end
|
32
|
+
|
33
|
+
def account
|
34
|
+
@account ||= SepaFileParser::Account.from_pain_data(
|
35
|
+
xml_data,
|
36
|
+
currency,
|
37
|
+
'Cdtr',
|
38
|
+
)
|
39
|
+
end
|
40
|
+
|
41
|
+
def remittance_information
|
42
|
+
@remittance_information ||= xml_data.xpath('RmtInf/Ustrd').text
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SepaFileParser
|
4
|
+
class PostalAddress
|
5
|
+
|
6
|
+
attr_reader :xml_data
|
7
|
+
|
8
|
+
def initialize(xml_data)
|
9
|
+
@xml_data = xml_data
|
10
|
+
end
|
11
|
+
|
12
|
+
# @return [Array<String>]
|
13
|
+
def lines # May be empty
|
14
|
+
xml_data.xpath('AdrLine').map do |x|
|
15
|
+
x.xpath('text()').text
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
# @return [String]
|
20
|
+
def street_name # May be missing
|
21
|
+
xml_data.xpath('StrtNm/text()').text
|
22
|
+
end
|
23
|
+
|
24
|
+
# @return [String]
|
25
|
+
def building_number # May be missing
|
26
|
+
xml_data.xpath('BldgNb/text()').text
|
27
|
+
end
|
28
|
+
|
29
|
+
# @return [String]
|
30
|
+
def postal_code # May be missing
|
31
|
+
xml_data.xpath('PstCd/text()').text
|
32
|
+
end
|
33
|
+
|
34
|
+
# @return [String]
|
35
|
+
def town_name # May be missing
|
36
|
+
xml_data.xpath('TwnNm/text()').text
|
37
|
+
end
|
38
|
+
|
39
|
+
# @return [String]
|
40
|
+
def country # May be missing
|
41
|
+
xml_data.xpath('Ctry/text()').text
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SepaFileParser
|
4
|
+
class Record
|
5
|
+
|
6
|
+
attr_reader :xml_data
|
7
|
+
|
8
|
+
def initialize(xml_data)
|
9
|
+
@xml_data = xml_data
|
10
|
+
@amount = xml_data.xpath('Amt/text()').text
|
11
|
+
end
|
12
|
+
|
13
|
+
def amount
|
14
|
+
SepaFileParser::Misc.to_amount(@amount)
|
15
|
+
end
|
16
|
+
|
17
|
+
def amount_in_cents
|
18
|
+
SepaFileParser::Misc.to_amount_in_cents(@amount)
|
19
|
+
end
|
20
|
+
|
21
|
+
def currency
|
22
|
+
@currency ||= xml_data.xpath('Amt/@Ccy').text
|
23
|
+
end
|
24
|
+
|
25
|
+
def type
|
26
|
+
@type ||= SepaFileParser::Type::Builder.build_type(xml_data.xpath('Tp'))
|
27
|
+
end
|
28
|
+
|
29
|
+
def charges_included?
|
30
|
+
@charges_included ||= xml_data.xpath('ChrgInclInd/text()').text.downcase == 'true'
|
31
|
+
end
|
32
|
+
|
33
|
+
def debit
|
34
|
+
@debit ||= xml_data.xpath('CdtDbtInd/text()').text.upcase == 'DBIT'
|
35
|
+
end
|
36
|
+
|
37
|
+
def credit?
|
38
|
+
!debit
|
39
|
+
end
|
40
|
+
|
41
|
+
def debit?
|
42
|
+
debit
|
43
|
+
end
|
44
|
+
|
45
|
+
def sign
|
46
|
+
credit? ? 1 : -1
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,139 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SepaFileParser
|
4
|
+
class Transaction
|
5
|
+
|
6
|
+
attr_reader :xml_data
|
7
|
+
|
8
|
+
def initialize(xml_data, debit, amount = nil, currency = nil)
|
9
|
+
@xml_data = xml_data
|
10
|
+
@debit = debit
|
11
|
+
@amount = parse_amount || amount
|
12
|
+
@currency = parse_currency || currency
|
13
|
+
end
|
14
|
+
|
15
|
+
def amount
|
16
|
+
SepaFileParser::Misc.to_amount(@amount)
|
17
|
+
end
|
18
|
+
|
19
|
+
def amount_in_cents
|
20
|
+
SepaFileParser::Misc.to_amount_in_cents(@amount)
|
21
|
+
end
|
22
|
+
|
23
|
+
def currency
|
24
|
+
@currency
|
25
|
+
end
|
26
|
+
|
27
|
+
def creditor
|
28
|
+
@creditor ||= SepaFileParser::Creditor.new(xml_data)
|
29
|
+
end
|
30
|
+
|
31
|
+
def debitor
|
32
|
+
@debitor ||= SepaFileParser::Debitor.new(xml_data)
|
33
|
+
end
|
34
|
+
|
35
|
+
def name
|
36
|
+
credit? ? debitor.name : creditor.name
|
37
|
+
end
|
38
|
+
|
39
|
+
def iban
|
40
|
+
credit? ? debitor.iban : creditor.iban
|
41
|
+
end
|
42
|
+
|
43
|
+
def bic
|
44
|
+
credit? ? debitor.bic : creditor.bic
|
45
|
+
end
|
46
|
+
|
47
|
+
def postal_address
|
48
|
+
credit? ? debitor.postal_address : creditor.postal_address
|
49
|
+
end
|
50
|
+
|
51
|
+
def credit?
|
52
|
+
!debit
|
53
|
+
end
|
54
|
+
|
55
|
+
def debit?
|
56
|
+
debit
|
57
|
+
end
|
58
|
+
|
59
|
+
def debit
|
60
|
+
@debit
|
61
|
+
end
|
62
|
+
|
63
|
+
def sign
|
64
|
+
credit? ? 1 : -1
|
65
|
+
end
|
66
|
+
|
67
|
+
def remittance_information
|
68
|
+
@remittance_information ||= begin
|
69
|
+
if (x = xml_data.xpath('RmtInf/Ustrd')).empty?
|
70
|
+
nil
|
71
|
+
else
|
72
|
+
x.collect(&:content).join(' ')
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def swift_code
|
78
|
+
@swift_code ||= xml_data.xpath('BkTxCd/Prtry/Cd/text()').text.split('+')[0]
|
79
|
+
end
|
80
|
+
|
81
|
+
def reference
|
82
|
+
@reference ||= xml_data.xpath('Refs/InstrId/text()').text
|
83
|
+
end
|
84
|
+
|
85
|
+
def bank_reference # May be missing
|
86
|
+
@bank_reference ||= xml_data.xpath('Refs/AcctSvcrRef/text()').text
|
87
|
+
end
|
88
|
+
|
89
|
+
def end_to_end_reference # May be missing
|
90
|
+
@end_to_end_reference ||= xml_data.xpath('Refs/EndToEndId/text()').text
|
91
|
+
end
|
92
|
+
|
93
|
+
def mandate_reference # May be missing
|
94
|
+
@mandate_reference ||= xml_data.xpath('Refs/MndtId/text()').text
|
95
|
+
end
|
96
|
+
|
97
|
+
def creditor_reference # May be missing
|
98
|
+
@creditor_reference ||= xml_data.xpath('RmtInf/Strd/CdtrRefInf/Ref/text()').text
|
99
|
+
end
|
100
|
+
|
101
|
+
def transaction_id # May be missing
|
102
|
+
@transaction_id ||= xml_data.xpath('Refs/TxId/text()').text
|
103
|
+
end
|
104
|
+
|
105
|
+
def creditor_identifier # May be missing
|
106
|
+
@creditor_identifier ||= xml_data.xpath('RltdPties/Cdtr/Id/PrvtId/Othr/Id/text()').text
|
107
|
+
end
|
108
|
+
|
109
|
+
def payment_information # May be missing
|
110
|
+
@payment_information ||= xml_data.xpath('Refs/PmtInfId/text()').text
|
111
|
+
end
|
112
|
+
|
113
|
+
def additional_information # May be missing
|
114
|
+
@addition_information ||= xml_data.xpath('AddtlTxInf/text()').text
|
115
|
+
end
|
116
|
+
|
117
|
+
def reason_code # May be missing
|
118
|
+
@reason_code ||= xml_data.xpath('RtrInf/Rsn/Cd/text()').text
|
119
|
+
end
|
120
|
+
|
121
|
+
private
|
122
|
+
|
123
|
+
def parse_amount
|
124
|
+
if xml_data.xpath('Amt').any?
|
125
|
+
xml_data.xpath('Amt/text()').text
|
126
|
+
elsif xml_data.xpath('AmtDtls').any?
|
127
|
+
xml_data.xpath('AmtDtls//Amt/text()').first.text
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
def parse_currency
|
132
|
+
if xml_data.xpath('Amt').any?
|
133
|
+
xml_data.xpath('Amt/@Ccy').text
|
134
|
+
elsif xml_data.xpath('AmtDtls').any?
|
135
|
+
xml_data.xpath('AmtDtls//Amt/@Ccy').first.text
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SepaFileParser
|
4
|
+
module Type
|
5
|
+
class Builder
|
6
|
+
def self.build_type(xml_data)
|
7
|
+
if xml_data.xpath('Prtry').any?
|
8
|
+
Proprietary.new(
|
9
|
+
xml_data.xpath('Prtry/Id/text()').text,
|
10
|
+
xml_data.xpath('Prtry/Issr/text()').text
|
11
|
+
)
|
12
|
+
elsif xml_data.xpath('Cd').any?
|
13
|
+
Code.new(xml_data.xpath('Cd/text()').text)
|
14
|
+
else
|
15
|
+
nil
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SepaFileParser
|
4
|
+
class Misc
|
5
|
+
class << self
|
6
|
+
|
7
|
+
# @param value [nil, String]
|
8
|
+
# @return [Integer, nil]
|
9
|
+
def to_amount_in_cents(value)
|
10
|
+
return nil if value == nil || value.strip == ''
|
11
|
+
|
12
|
+
# Using dollars and cents as representation for parts before and after the decimal separator
|
13
|
+
dollars, cents = value.split(/,|\./)
|
14
|
+
cents ||= '0'
|
15
|
+
format('%s%s', dollars, cents.ljust(2, '0')).to_i
|
16
|
+
end
|
17
|
+
|
18
|
+
# @param value [nil, String]
|
19
|
+
# @return [BigDecimal, nil]
|
20
|
+
def to_amount(value)
|
21
|
+
return nil if value == nil || value.strip == ''
|
22
|
+
|
23
|
+
BigDecimal(value.tr(',', '.'))
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SepaFileParser
|
4
|
+
module Pain001
|
5
|
+
class Base
|
6
|
+
attr_reader :group_header, :payment_informations, :xml_data
|
7
|
+
|
8
|
+
def initialize(xml_data)
|
9
|
+
@xml_data = xml_data
|
10
|
+
# CstmrCdtTrfInitn = Customer Credit Transaction Initiation
|
11
|
+
grphdr = xml_data.xpath('CstmrCdtTrfInitn/GrpHdr')
|
12
|
+
@group_header = SepaFileParser::GroupHeader.new(grphdr)
|
13
|
+
payment_informations = xml_data.xpath('CstmrCdtTrfInitn/PmtInf')
|
14
|
+
@payment_informations = payment_informations.map{ |x| PaymentInformation.new(x) }
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SepaFileParser
|
4
|
+
module Pain001
|
5
|
+
class PaymentInformation
|
6
|
+
|
7
|
+
attr_reader :xml_data
|
8
|
+
|
9
|
+
def initialize(xml_data)
|
10
|
+
@xml_data = xml_data
|
11
|
+
end
|
12
|
+
|
13
|
+
def identification
|
14
|
+
@identification ||= xml_data.xpath('PmtInfId/text()').text
|
15
|
+
end
|
16
|
+
|
17
|
+
def requested_execution_date
|
18
|
+
@requested_execution_date ||= Time.parse(xml_data.xpath('ReqdExctnDt/text()').text)
|
19
|
+
end
|
20
|
+
|
21
|
+
def account
|
22
|
+
@account ||= SepaFileParser::Account.from_pain_data(
|
23
|
+
xml_data,
|
24
|
+
entries.first.currency,
|
25
|
+
'Dbtr',
|
26
|
+
)
|
27
|
+
end
|
28
|
+
|
29
|
+
def entries
|
30
|
+
@entries ||= xml_data.xpath('CdtTrfTxInf').map do |x|
|
31
|
+
SepaFileParser::PainEntry.new(x)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def source
|
36
|
+
xml_data.to_s
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.parse(xml)
|
40
|
+
self.new(Nokogiri::XML(xml).xpath('PmtInf'))
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SepaFileParser
|
4
|
+
module Pain008
|
5
|
+
class Base
|
6
|
+
attr_reader :group_header, :payment_informations, :xml_data
|
7
|
+
|
8
|
+
def initialize(xml_data)
|
9
|
+
@xml_data = xml_data
|
10
|
+
# CstmrDrctDbtInitn = Customer Direct Debig Initiation
|
11
|
+
grphdr = xml_data.xpath('CstmrDrctDbtInitn/GrpHdr')
|
12
|
+
@group_header = SepaFileParser::GroupHeader.new(grphdr)
|
13
|
+
payment_informations = xml_data.xpath('CstmrDrctDbtInitn/PmtInf')
|
14
|
+
@payment_informations = payment_informations.map{ |x| PaymentInformation.new(x) }
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SepaFileParser
|
4
|
+
module Pain008
|
5
|
+
class PaymentInformation
|
6
|
+
|
7
|
+
attr_reader :xml_data
|
8
|
+
|
9
|
+
def initialize(xml_data)
|
10
|
+
@xml_data = xml_data
|
11
|
+
end
|
12
|
+
|
13
|
+
def identification
|
14
|
+
@identification ||= xml_data.xpath('PmtInfId/text()').text
|
15
|
+
end
|
16
|
+
|
17
|
+
def requested_collection_date
|
18
|
+
@requested_collection_date ||= Time.parse(xml_data.xpath('ReqdColltnDt/text()').text)
|
19
|
+
end
|
20
|
+
|
21
|
+
def account
|
22
|
+
@account ||= SepaFileParser::Account.from_pain_data(
|
23
|
+
xml_data,
|
24
|
+
entries.first.currency,
|
25
|
+
'Cdtr',
|
26
|
+
)
|
27
|
+
end
|
28
|
+
|
29
|
+
def entries
|
30
|
+
@entries ||= xml_data.xpath('DrctDbtTxInf').map do |x|
|
31
|
+
SepaFileParser::PainEntry.new(x)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def source
|
36
|
+
xml_data.to_s
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.parse(xml)
|
40
|
+
self.new(Nokogiri::XML(xml).xpath('PmtInf'))
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative './xml'
|
4
|
+
|
5
|
+
# Add registrations
|
6
|
+
## CAMT052
|
7
|
+
SepaFileParser::Xml.register('urn:iso:std:iso:20022:tech:xsd:camt.052.001.02', :camt052)
|
8
|
+
|
9
|
+
## CAMT053
|
10
|
+
SepaFileParser::Xml.register('urn:iso:std:iso:20022:tech:xsd:camt.053.001.02', :camt053)
|
11
|
+
SepaFileParser::Xml.register('urn:iso:std:iso:20022:tech:xsd:camt.053.001.04', :camt053)
|
12
|
+
SepaFileParser::Xml.register('urn:iso:std:iso:20022:tech:xsd:camt.053.001.08', :camt053)
|
13
|
+
SepaFileParser::Xml.register('urn:iso:std:iso:20022:tech:xsd:camt.053.001.10', :camt053)
|
14
|
+
|
15
|
+
## CAMT054
|
16
|
+
SepaFileParser::Xml.register('urn:iso:std:iso:20022:tech:xsd:camt.054.001.02', :camt054)
|
17
|
+
SepaFileParser::Xml.register('urn:iso:std:iso:20022:tech:xsd:camt.054.001.04', :camt054)
|
18
|
+
|
19
|
+
## PAIN001
|
20
|
+
SepaFileParser::Xml.register('urn:iso:std:iso:20022:tech:xsd:pain.001.001.03', :pain001)
|
21
|
+
|
22
|
+
## PAIN008
|
23
|
+
SepaFileParser::Xml.register('urn:iso:std:iso:20022:tech:xsd:pain.008.003.02', :pain008)
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SepaFileParser
|
4
|
+
class Xml
|
5
|
+
PARSER_MAPPING = {
|
6
|
+
camt052: SepaFileParser::Camt052::Base,
|
7
|
+
camt053: SepaFileParser::Camt053::Base,
|
8
|
+
camt054: SepaFileParser::Camt054::Base,
|
9
|
+
pain001: SepaFileParser::Pain001::Base,
|
10
|
+
pain008: SepaFileParser::Pain008::Base,
|
11
|
+
}.freeze
|
12
|
+
|
13
|
+
SUPPORTED_PARSERS = PARSER_MAPPING.keys.freeze
|
14
|
+
|
15
|
+
@namespace_parsers = {}
|
16
|
+
|
17
|
+
def self.register(namespace, parser)
|
18
|
+
if !SUPPORTED_PARSERS.include?(parser)
|
19
|
+
raise SepaFileParser::Errors::UnsupportedParserClass, parser.to_s
|
20
|
+
end
|
21
|
+
|
22
|
+
if @namespace_parsers.key?(namespace) # Prevent overwriting existing registrations
|
23
|
+
raise SepaFileParser::Errors::NamespaceAlreadyRegistered, namespace
|
24
|
+
end
|
25
|
+
|
26
|
+
@namespace_parsers[namespace] = PARSER_MAPPING[parser]
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.parse(doc)
|
30
|
+
if !doc.is_a?(Nokogiri::XML::Document)
|
31
|
+
raise SepaFileParser::Errors::NotXMLError, doc.class
|
32
|
+
end
|
33
|
+
|
34
|
+
namespace = doc.namespaces['xmlns']
|
35
|
+
doc.remove_namespaces!
|
36
|
+
|
37
|
+
parser_class = @namespace_parsers[namespace]
|
38
|
+
if parser_class == nil
|
39
|
+
raise SepaFileParser::Errors::UnsupportedNamespaceError, namespace
|
40
|
+
end
|
41
|
+
|
42
|
+
return parser_class.new(doc.xpath('Document'))
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'nokogiri'
|
4
|
+
require 'time'
|
5
|
+
require 'bigdecimal'
|
6
|
+
|
7
|
+
require_relative 'sepa_file_parser/misc'
|
8
|
+
require_relative 'sepa_file_parser/version'
|
9
|
+
require_relative 'sepa_file_parser/errors'
|
10
|
+
require_relative 'sepa_file_parser/general/account_balance'
|
11
|
+
require_relative 'sepa_file_parser/general/creditor'
|
12
|
+
require_relative 'sepa_file_parser/general/debitor'
|
13
|
+
require_relative 'sepa_file_parser/general/entry'
|
14
|
+
require_relative 'sepa_file_parser/general/record'
|
15
|
+
require_relative 'sepa_file_parser/general/charges'
|
16
|
+
require_relative 'sepa_file_parser/general/account'
|
17
|
+
require_relative 'sepa_file_parser/general/batch_detail'
|
18
|
+
require_relative 'sepa_file_parser/general/group_header'
|
19
|
+
require_relative 'sepa_file_parser/general/pain_entry'
|
20
|
+
require_relative 'sepa_file_parser/general/postal_address'
|
21
|
+
require_relative 'sepa_file_parser/general/transaction'
|
22
|
+
require_relative 'sepa_file_parser/general/type/builder'
|
23
|
+
require_relative 'sepa_file_parser/general/type/code'
|
24
|
+
require_relative 'sepa_file_parser/general/type/proprietary'
|
25
|
+
require_relative 'sepa_file_parser/camt052/report'
|
26
|
+
require_relative 'sepa_file_parser/camt052/base'
|
27
|
+
require_relative 'sepa_file_parser/camt053/statement'
|
28
|
+
require_relative 'sepa_file_parser/camt053/base'
|
29
|
+
require_relative 'sepa_file_parser/camt054/notification'
|
30
|
+
require_relative 'sepa_file_parser/camt054/base'
|
31
|
+
require_relative 'sepa_file_parser/pain001/payment_information'
|
32
|
+
require_relative 'sepa_file_parser/pain001/base'
|
33
|
+
require_relative 'sepa_file_parser/pain008/payment_information'
|
34
|
+
require_relative 'sepa_file_parser/pain008/base'
|
35
|
+
require_relative 'sepa_file_parser/file'
|
36
|
+
require_relative 'sepa_file_parser/string'
|
37
|
+
require_relative 'sepa_file_parser/register'
|
38
|
+
require_relative 'sepa_file_parser/xml'
|