camt_parser 2.14.0 → 2.15.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5a14cf208512428c2b5598f13c736e42e36e8d821cf74fdc9b729545387b1243
4
- data.tar.gz: faeb2af47c98f82135430e9586bf962ff2db1ea38b67720dd358b43156831a32
3
+ metadata.gz: b5aeab74fdc7446d278695d00616a5449870180088c7dc8daf1aa52a83897cfc
4
+ data.tar.gz: f032bd706926a5314a2c7f110f6053962b91f6a0e4222bb633c2094f98ac3d6b
5
5
  SHA512:
6
- metadata.gz: 841652ca51bd7e936feadd3f7b38a5df2bd5d18088d22bad9fc6e35c60a4519cfc4effa415c3985304a5cc3bea5943d9f9d713e659927af72cf5c760b93c24e4
7
- data.tar.gz: 0f8a1bfa248544999e7849d581b4eb2a88d7c80cb153d74b9a56a974c67d8e9525c54ff522c5f724799195fe7d5cb0a2366380f98975c9cf8334d58310b0b02b
6
+ metadata.gz: a59f2634bf67b442365cc7b32dd5c7c4295872e536af30dc8901a2a30a7499100a785f6a09df9e2b08494a4356b3227eb3622a747aa4f3ff6def6476f4132ab7
7
+ data.tar.gz: febcbdb49b56ac81342cd31ab5e6252071769a167a8221850e47b817f850e90ef6fb25a3920f360be550fc58209e024a76b56678b3cd327d7367f54769412829
@@ -1,9 +1,10 @@
1
1
  module CamtParser
2
2
  module Format052
3
3
  class Base
4
- attr_reader :group_header, :reports
4
+ attr_reader :group_header, :reports, :xml_data
5
5
 
6
6
  def initialize(xml_data)
7
+ @xml_data = xml_data
7
8
  # BkToCstmrAccptRpt = Bank to Customer Account Report
8
9
  grphdr = xml_data.xpath('BkToCstmrAcctRpt/GrpHdr')
9
10
  @group_header = CamtParser::GroupHeader.new(grphdr)
@@ -1,41 +1,44 @@
1
1
  module CamtParser
2
2
  module Format052
3
3
  class Report
4
+
5
+ attr_reader :xml_data
6
+
4
7
  def initialize(xml_data)
5
8
  @xml_data = xml_data
6
9
  end
7
10
 
8
11
  def identification
9
- @identification ||= @xml_data.xpath('Id/text()').text
12
+ @identification ||= xml_data.xpath('Id/text()').text
10
13
  end
11
14
 
12
15
  def generation_date
13
- @generation_date ||= Time.parse(@xml_data.xpath('CreDtTm/text()').text)
16
+ @generation_date ||= Time.parse(xml_data.xpath('CreDtTm/text()').text)
14
17
  end
15
18
 
16
19
  def account
17
- @account ||= CamtParser::Account.new(@xml_data.xpath('Acct').first)
20
+ @account ||= CamtParser::Account.new(xml_data.xpath('Acct').first)
18
21
  end
19
22
 
20
23
  def entries
21
- @entries ||= @xml_data.xpath('Ntry').map{ |x| CamtParser::Entry.new(x) }
24
+ @entries ||= xml_data.xpath('Ntry').map{ |x| CamtParser::Entry.new(x) }
22
25
  end
23
26
 
24
27
  def legal_sequence_number
25
- @legal_sequence_number ||= @xml_data.xpath('LglSeqNb/text()').text
28
+ @legal_sequence_number ||= xml_data.xpath('LglSeqNb/text()').text
26
29
  end
27
30
 
28
31
  def from_date_time
29
- @from_date_time ||= (x = @xml_data.xpath('FrToDt/FrDtTm')).empty? ? nil : Time.parse(x.first.content)
32
+ @from_date_time ||= (x = xml_data.xpath('FrToDt/FrDtTm')).empty? ? nil : Time.parse(x.first.content)
30
33
  end
31
34
 
32
35
  def to_date_time
33
- @to_date_time ||= (x = @xml_data.xpath('FrToDt/ToDtTm')).empty? ? nil : Time.parse(x.first.content)
36
+ @to_date_time ||= (x = xml_data.xpath('FrToDt/ToDtTm')).empty? ? nil : Time.parse(x.first.content)
34
37
  end
35
38
 
36
39
  def opening_balance
37
40
  @opening_balance ||= begin
38
- bal = @xml_data.xpath('Bal/Tp//Cd[contains(text(), "PRCD")]').first.ancestors('Bal')
41
+ bal = xml_data.xpath('Bal/Tp//Cd[contains(text(), "PRCD")]').first.ancestors('Bal')
39
42
  date = bal.xpath('Dt/Dt/text()').text
40
43
  credit = bal.xpath('CdtDbtInd/text()').text == 'CRDT'
41
44
  currency = bal.xpath('Amt').attribute('Ccy').value
@@ -46,7 +49,7 @@ module CamtParser
46
49
 
47
50
  def closing_balance
48
51
  @closing_balance ||= begin
49
- bal = @xml_data.xpath('Bal/Tp//Cd[contains(text(), "CLBD")]').first.ancestors('Bal')
52
+ bal = xml_data.xpath('Bal/Tp//Cd[contains(text(), "CLBD")]').first.ancestors('Bal')
50
53
  date = bal.xpath('Dt/Dt/text()').text
51
54
  credit = bal.xpath('CdtDbtInd/text()').text == 'CRDT'
52
55
  currency = bal.xpath('Amt').attribute('Ccy').value
@@ -57,7 +60,7 @@ module CamtParser
57
60
 
58
61
 
59
62
  def source
60
- @xml_data.to_s
63
+ xml_data.to_s
61
64
  end
62
65
 
63
66
  def self.parse(xml)
@@ -1,9 +1,11 @@
1
1
  module CamtParser
2
2
  module Format053
3
3
  class Base
4
- attr_reader :group_header, :statements
4
+ attr_reader :group_header, :statements, :xml_data
5
5
 
6
6
  def initialize(xml_data)
7
+ @xml_data = xml_data
8
+
7
9
  grphdr = xml_data.xpath('BkToCstmrStmt/GrpHdr')
8
10
  @group_header = GroupHeader.new(grphdr)
9
11
  statements = xml_data.xpath('BkToCstmrStmt/Stmt')
@@ -1,45 +1,48 @@
1
1
  module CamtParser
2
2
  module Format053
3
3
  class Statement
4
+
5
+ attr_reader :xml_data
6
+
4
7
  def initialize(xml_data)
5
8
  @xml_data = xml_data
6
9
  end
7
10
 
8
11
  def identification
9
- @identification ||= @xml_data.xpath('Id/text()').text
12
+ @identification ||= xml_data.xpath('Id/text()').text
10
13
  end
11
14
 
12
15
  def generation_date
13
- @generation_date ||= Time.parse(@xml_data.xpath('CreDtTm/text()').text)
16
+ @generation_date ||= Time.parse(xml_data.xpath('CreDtTm/text()').text)
14
17
  end
15
18
 
16
19
  def from_date_time
17
- @from_date_time ||= (x = @xml_data.xpath('FrToDt/FrDtTm')).empty? ? nil : Time.parse(x.first.content)
20
+ @from_date_time ||= (x = xml_data.xpath('FrToDt/FrDtTm')).empty? ? nil : Time.parse(x.first.content)
18
21
  end
19
22
 
20
23
  def to_date_time
21
- @to_date_time ||= (x = @xml_data.xpath('FrToDt/ToDtTm')).empty? ? nil : Time.parse(x.first.content)
24
+ @to_date_time ||= (x = xml_data.xpath('FrToDt/ToDtTm')).empty? ? nil : Time.parse(x.first.content)
22
25
  end
23
26
 
24
27
  def account
25
- @account ||= Account.new(@xml_data.xpath('Acct').first)
28
+ @account ||= Account.new(xml_data.xpath('Acct').first)
26
29
  end
27
30
 
28
31
  def entries
29
- @entries ||= @xml_data.xpath('Ntry').map{ |x| Entry.new(x) }
32
+ @entries ||= xml_data.xpath('Ntry').map{ |x| Entry.new(x) }
30
33
  end
31
34
 
32
35
  def legal_sequence_number
33
- @legal_sequence_number ||= @xml_data.xpath('LglSeqNb/text()').text
36
+ @legal_sequence_number ||= xml_data.xpath('LglSeqNb/text()').text
34
37
  end
35
38
 
36
39
  def electronic_sequence_number
37
- @electronic_sequence_number ||= @xml_data.xpath('ElctrncSeqNb/text()').text
40
+ @electronic_sequence_number ||= xml_data.xpath('ElctrncSeqNb/text()').text
38
41
  end
39
42
 
40
43
  def opening_balance
41
44
  @opening_balance ||= begin
42
- bal = @xml_data.xpath('Bal/Tp//Cd[contains(text(), "OPBD") or contains(text(), "PRCD")]').first.ancestors('Bal')
45
+ bal = xml_data.xpath('Bal/Tp//Cd[contains(text(), "OPBD") or contains(text(), "PRCD")]').first.ancestors('Bal')
43
46
  date = bal.xpath('Dt/Dt/text()').text
44
47
  credit = bal.xpath('CdtDbtInd/text()').text == 'CRDT'
45
48
  currency = bal.xpath('Amt').attribute('Ccy').value
@@ -49,7 +52,7 @@ module CamtParser
49
52
 
50
53
  def closing_balance
51
54
  @closing_balance ||= begin
52
- bal = @xml_data.xpath('Bal/Tp//Cd[contains(text(), "CLBD")]').first.ancestors('Bal')
55
+ bal = xml_data.xpath('Bal/Tp//Cd[contains(text(), "CLBD")]').first.ancestors('Bal')
53
56
  date = bal.xpath('Dt/Dt/text()').text
54
57
  credit = bal.xpath('CdtDbtInd/text()').text == 'CRDT'
55
58
  currency = bal.xpath('Amt').attribute('Ccy').value
@@ -59,7 +62,7 @@ module CamtParser
59
62
  alias_method :closing_or_intermediary_balance, :closing_balance
60
63
 
61
64
  def source
62
- @xml_data.to_s
65
+ xml_data.to_s
63
66
  end
64
67
 
65
68
  def self.parse(xml)
@@ -1,9 +1,11 @@
1
1
  module CamtParser
2
2
  module Format054
3
3
  class Base
4
- attr_reader :group_header, :notifications
4
+ attr_reader :group_header, :notifications, :xml_data
5
5
 
6
6
  def initialize(xml_data)
7
+ @xml_data = xml_data
8
+
7
9
  grphdr = xml_data.xpath('BkToCstmrDbtCdtNtfctn/GrpHdr')
8
10
  @group_header = GroupHeader.new(grphdr)
9
11
  notifications = xml_data.xpath('BkToCstmrDbtCdtNtfctn/Ntfctn')
@@ -1,38 +1,49 @@
1
1
  module CamtParser
2
2
  module Format054
3
3
  class Notification
4
+
5
+ attr_reader :xml_data
6
+
4
7
  def initialize(xml_data)
5
8
  @xml_data = xml_data
6
9
  end
7
10
 
11
+ # @return [String]
8
12
  def identification
9
- @identification ||= @xml_data.xpath('Id/text()').text
13
+ @identification ||= xml_data.xpath('Id/text()').text
10
14
  end
11
15
 
16
+ # @return [Time]
12
17
  def generation_date
13
- @generation_date ||= Time.parse(@xml_data.xpath('CreDtTm/text()').text)
18
+ @generation_date ||= Time.parse(xml_data.xpath('CreDtTm/text()').text)
14
19
  end
15
20
 
21
+ # @return [Time, nil]
16
22
  def from_date_time
17
- @from_date_time ||= (x = @xml_data.xpath('FrToDt/FrDtTm')).empty? ? nil : Time.parse(x.first.content)
23
+ @from_date_time ||= (x = xml_data.xpath('FrToDt/FrDtTm')).empty? ? nil : Time.parse(x.first.content)
18
24
  end
19
25
 
26
+ # @return [Time, nil]
20
27
  def to_date_time
21
- @to_date_time ||= (x = @xml_data.xpath('FrToDt/ToDtTm')).empty? ? nil : Time.parse(x.first.content)
28
+ @to_date_time ||= (x = xml_data.xpath('FrToDt/ToDtTm')).empty? ? nil : Time.parse(x.first.content)
22
29
  end
23
30
 
31
+ # @return [Account]
24
32
  def account
25
- @account ||= Account.new(@xml_data.xpath('Acct').first)
33
+ @account ||= Account.new(xml_data.xpath('Acct').first)
26
34
  end
27
35
 
36
+ # @return [Array<Entry>]
28
37
  def entries
29
- @entries ||= @xml_data.xpath('Ntry').map{ |x| Entry.new(x) }
38
+ @entries ||= xml_data.xpath('Ntry').map{ |x| Entry.new(x) }
30
39
  end
31
40
 
41
+ # @return [String]
32
42
  def source
33
- @xml_data.to_s
43
+ xml_data.to_s
34
44
  end
35
45
 
46
+ # @return [CamtParser::Format054::Notification]
36
47
  def self.parse(xml)
37
48
  self.new Nokogiri::XML(xml).xpath('Ntfctn')
38
49
  end
@@ -1,31 +1,43 @@
1
1
  module CamtParser
2
2
  class Account
3
+
4
+ attr_reader :xml_data
5
+
3
6
  def initialize(xml_data)
4
7
  @xml_data = xml_data
5
8
  end
6
9
 
10
+ # @return [String]
7
11
  def iban
8
- @iban ||= @xml_data.xpath('Id/IBAN/text()').text
12
+ @iban ||= xml_data.xpath('Id/IBAN/text()').text
9
13
  end
10
14
 
15
+ # @return [String]
11
16
  def other_id
12
- @other_id ||= @xml_data.xpath('Id/Othr/Id/text()').text
17
+ @other_id ||= xml_data.xpath('Id/Othr/Id/text()').text
13
18
  end
14
19
 
20
+ # @return [String]
15
21
  def account_number
16
22
  !iban.nil? && !iban.empty? ? iban : other_id
17
23
  end
18
24
 
25
+ # @return [String]
19
26
  def bic
20
- @bic ||= @xml_data.xpath('Svcr/FinInstnId/BIC/text()').text
27
+ @bic ||= [
28
+ xml_data.xpath('Svcr/FinInstnId/BIC/text()').text,
29
+ xml_data.xpath('Svcr/FinInstnId/BICFI/text()').text,
30
+ ].reject(&:empty?).first.to_s
21
31
  end
22
32
 
33
+ # @return [String]
23
34
  def bank_name
24
- @bank_name ||= @xml_data.xpath('Svcr/FinInstnId/Nm/text()').text
35
+ @bank_name ||= xml_data.xpath('Svcr/FinInstnId/Nm/text()').text
25
36
  end
26
37
 
38
+ # @return [String]
27
39
  def currency
28
- @currency ||= @xml_data.xpath('Ccy/text()').text
40
+ @currency ||= xml_data.xpath('Ccy/text()').text
29
41
  end
30
42
  end
31
43
  end
@@ -1,6 +1,10 @@
1
1
  module CamtParser
2
2
  class AccountBalance
3
3
 
4
+ # @param amount [String]
5
+ # @param currency [String]
6
+ # @param date [String]
7
+ # @param credit [Boolean]
4
8
  def initialize(amount, currency, date, credit = false)
5
9
  @amount = amount
6
10
  @currency = currency
@@ -8,34 +12,42 @@ module CamtParser
8
12
  @credit = credit
9
13
  end
10
14
 
15
+ # @return [String]
11
16
  def currency
12
17
  @currency
13
18
  end
14
19
 
20
+ # @return [Date]
15
21
  def date
16
22
  Date.parse @date
17
23
  end
18
24
 
25
+ # @return [Integer] either 1 or -1
19
26
  def sign
20
27
  credit? ? 1 : -1
21
28
  end
22
29
 
30
+ # @return [Boolean]
23
31
  def credit?
24
32
  @credit
25
33
  end
26
34
 
35
+ # @return [BigDecimal]
27
36
  def amount
28
37
  CamtParser::Misc.to_amount(@amount)
29
38
  end
30
39
 
40
+ # @return [Integer]
31
41
  def amount_in_cents
32
42
  CamtParser::Misc.to_amount_in_cents(@amount)
33
43
  end
34
44
 
45
+ # @return [BigDecimal]
35
46
  def signed_amount
36
47
  amount * sign
37
48
  end
38
49
 
50
+ # @return [Hash{String => BigDecimal, Integer}]
39
51
  def to_h
40
52
  {
41
53
  'amount' => amount,
@@ -1,19 +1,22 @@
1
1
  module CamtParser
2
2
  class BatchDetail
3
+
4
+ attr_reader :xml_data
5
+
3
6
  def initialize(xml_data)
4
7
  @xml_data = xml_data
5
8
  end
6
9
 
7
10
  def payment_information_identification
8
- @payment_information_identification ||= @xml_data.xpath('PmtInfId/text()').text
11
+ @payment_information_identification ||= xml_data.xpath('PmtInfId/text()').text
9
12
  end
10
13
 
11
14
  def msg_id # may be missing
12
- @msg_id ||= @xml_data.xpath('MsgId/text()').text
15
+ @msg_id ||= xml_data.xpath('MsgId/text()').text
13
16
  end
14
17
 
15
18
  def number_of_transactions
16
- @number_of_transactions ||= @xml_data.xpath('NbOfTxs/text()').text
19
+ @number_of_transactions ||= xml_data.xpath('NbOfTxs/text()').text
17
20
  end
18
21
  end
19
22
  end
@@ -1,8 +1,11 @@
1
1
  module CamtParser
2
2
  class Charges
3
+
4
+ attr_reader :xml_data
5
+
3
6
  def initialize(xml_data)
4
7
  @xml_data = xml_data
5
- @total_charges_and_tax_amount = @xml_data.xpath('TtlChrgsAndTaxAmt/text()').text
8
+ @total_charges_and_tax_amount = xml_data.xpath('TtlChrgsAndTaxAmt/text()').text
6
9
  end
7
10
 
8
11
  def total_charges_and_tax_amount
@@ -14,7 +17,7 @@ module CamtParser
14
17
  end
15
18
 
16
19
  def records
17
- @records ||= @xml_data.xpath('Rcrd').map{ |x| CamtParser::Record.new(x) }
20
+ @records ||= xml_data.xpath('Rcrd').map{ |x| CamtParser::Record.new(x) }
18
21
  end
19
22
  end
20
23
  end
@@ -1,23 +1,32 @@
1
1
  module CamtParser
2
2
  class Creditor
3
+
4
+ attr_reader :xml_data
5
+
3
6
  def initialize(xml_data)
4
7
  @xml_data = xml_data
5
8
  end
6
9
 
7
10
  def name
8
- @name ||= @xml_data.xpath('RltdPties/Cdtr/Nm/text()').text
11
+ @name ||= [
12
+ xml_data.xpath('RltdPties/Cdtr/Nm/text()').text,
13
+ xml_data.xpath('RltdPties/Cdtr/Pty/Nm/text()').text,
14
+ ].reject(&:empty?).first.to_s
9
15
  end
10
16
 
11
17
  def iban
12
- @iban ||= @xml_data.xpath('RltdPties/CdtrAcct/Id/IBAN/text()').text
18
+ @iban ||= xml_data.xpath('RltdPties/CdtrAcct/Id/IBAN/text()').text
13
19
  end
14
20
 
15
21
  def bic
16
- @bic ||= @xml_data.xpath('RltdAgts/CdtrAgt/FinInstnId/BIC/text()').text
22
+ @bic ||= [
23
+ xml_data.xpath('RltdAgts/CdtrAgt/FinInstnId/BIC/text()').text,
24
+ xml_data.xpath('RltdAgts/CdtrAgt/FinInstnId/BICFI/text()').text,
25
+ ].reject(&:empty?).first.to_s
17
26
  end
18
27
 
19
28
  def bank_name
20
- @bank_name ||= @xml_data.xpath('RltdAgts/CdtrAgt/FinInstnId/Nm/text()').text
29
+ @bank_name ||= xml_data.xpath('RltdAgts/CdtrAgt/FinInstnId/Nm/text()').text
21
30
  end
22
31
  end
23
32
  end
@@ -1,23 +1,32 @@
1
1
  module CamtParser
2
2
  class Debitor
3
+
4
+ attr_reader :xml_data
5
+
3
6
  def initialize(xml_data)
4
7
  @xml_data = xml_data
5
8
  end
6
9
 
7
10
  def name
8
- @name ||= @xml_data.xpath('RltdPties/Dbtr/Nm/text()').text
11
+ @name ||= [
12
+ xml_data.xpath('RltdPties/Dbtr/Nm/text()').text,
13
+ xml_data.xpath('RltdPties/Dbtr/Pty/Nm/text()').text,
14
+ ].reject(&:empty?).first.to_s
9
15
  end
10
16
 
11
17
  def iban
12
- @iban ||= @xml_data.xpath('RltdPties/DbtrAcct/Id/IBAN/text()').text
18
+ @iban ||= xml_data.xpath('RltdPties/DbtrAcct/Id/IBAN/text()').text
13
19
  end
14
20
 
15
21
  def bic
16
- @bic ||= @xml_data.xpath('RltdAgts/DbtrAgt/FinInstnId/BIC/text()').text
22
+ @bic ||= [
23
+ xml_data.xpath('RltdAgts/DbtrAgt/FinInstnId/BIC/text()').text,
24
+ xml_data.xpath('RltdAgts/DbtrAgt/FinInstnId/BICFI/text()').text,
25
+ ].reject(&:empty?).first.to_s
17
26
  end
18
27
 
19
28
  def bank_name
20
- @bank_name ||= @xml_data.xpath('RltdAgts/DbtrAgt/FinInstnId/Nm/text()').text
29
+ @bank_name ||= xml_data.xpath('RltdAgts/DbtrAgt/FinInstnId/Nm/text()').text
21
30
  end
22
31
  end
23
32
  end
@@ -1,8 +1,11 @@
1
1
  module CamtParser
2
2
  class Entry
3
+
4
+ attr_reader :xml_data
5
+
3
6
  def initialize(xml_data)
4
7
  @xml_data = xml_data
5
- @amount = @xml_data.xpath('Amt/text()').text
8
+ @amount = xml_data.xpath('Amt/text()').text
6
9
  end
7
10
 
8
11
  def amount
@@ -13,78 +16,100 @@ module CamtParser
13
16
  CamtParser::Misc.to_amount_in_cents(@amount)
14
17
  end
15
18
 
19
+ # @return [String]
16
20
  def currency
17
- @currency ||= @xml_data.xpath('Amt/@Ccy').text
21
+ @currency ||= xml_data.xpath('Amt/@Ccy').text
18
22
  end
19
23
 
24
+ # @return [Boolean]
20
25
  def debit
21
- @debit ||= @xml_data.xpath('CdtDbtInd/text()').text.upcase == 'DBIT'
26
+ @debit ||= xml_data.xpath('CdtDbtInd/text()').text.upcase == 'DBIT'
22
27
  end
23
28
 
29
+ # @return [Date]
24
30
  def value_date
25
- @value_date ||= Date.parse(@xml_data.xpath('ValDt/Dt/text()').text)
31
+ @value_date ||= ((date = xml_data.xpath('ValDt/Dt/text()').text).empty? ? nil : Date.parse(date))
26
32
  end
27
33
 
34
+ # @return [Date]
28
35
  def booking_date
29
- @booking_date ||= Date.parse(@xml_data.xpath('BookgDt/Dt/text()').text)
36
+ @booking_date ||= ((date = xml_data.xpath('BookgDt/Dt/text()').text).empty? ? nil : Date.parse(date))
37
+ end
38
+
39
+ # @return [DateTime]
40
+ def value_datetime
41
+ @value_datetime ||= ((datetime = xml_data.xpath('ValDt/DtTm/text()').text).empty? ? nil : DateTime.parse(datetime))
30
42
  end
31
43
 
44
+ # @return [DateTime]
45
+ def booking_datetime
46
+ @booking_datetime ||= ((datetime = xml_data.xpath('BookgDt/DtTm/text()').text).empty? ? nil : DateTime.parse(datetime))
47
+ end
48
+
49
+ # @return [String]
32
50
  def bank_reference # May be missing
33
- @bank_reference ||= @xml_data.xpath('AcctSvcrRef/text()').text
51
+ @bank_reference ||= xml_data.xpath('AcctSvcrRef/text()').text
34
52
  end
35
53
 
54
+ # @return [Array<CamtParser::Transaction>]
36
55
  def transactions
37
56
  @transactions ||= parse_transactions
38
57
  end
39
58
 
59
+ # @return [Boolean]
40
60
  def credit?
41
61
  !debit
42
62
  end
43
63
 
64
+ # @return [Boolean]
44
65
  def debit?
45
66
  debit
46
67
  end
47
68
 
69
+ # @return [Integer] either 1 or -1
48
70
  def sign
49
71
  credit? ? 1 : -1
50
72
  end
51
73
 
74
+ # @return [Boolean]
52
75
  def reversal?
53
- @reversal ||= @xml_data.xpath('RvslInd/text()').text.downcase == 'true'
76
+ @reversal ||= xml_data.xpath('RvslInd/text()').text.downcase == 'true'
54
77
  end
55
78
 
79
+ # @return [Boolean]
56
80
  def booked?
57
- @booked ||= @xml_data.xpath('Sts/text()').text.upcase == 'BOOK'
81
+ @booked ||= xml_data.xpath('Sts/text()').text.upcase == 'BOOK'
58
82
  end
59
83
 
84
+ # @return [String]
60
85
  def additional_information
61
- @additional_information ||= @xml_data.xpath('AddtlNtryInf/text()').text
86
+ @additional_information ||= xml_data.xpath('AddtlNtryInf/text()').text
62
87
  end
63
88
  alias_method :description, :additional_information
64
89
 
90
+ # @return [CamtParser::Charges]
65
91
  def charges
66
- @charges ||= CamtParser::Charges.new(@xml_data.xpath('Chrgs'))
92
+ @charges ||= CamtParser::Charges.new(xml_data.xpath('Chrgs'))
67
93
  end
68
-
94
+ # @return [CamtParser::BatchDetail, nil]
69
95
  def batch_detail
70
- @batch_detail ||= @xml_data.xpath('NtryDtls/Btch').empty? ? nil : CamtParser::BatchDetail.new(@xml_data.xpath('NtryDtls/Btch'))
71
- end
96
+ @batch_detail ||= xml_data.xpath('NtryDtls/Btch').empty? ? nil : CamtParser::BatchDetail.new(@xml_data.xpath('NtryDtls/Btch'))
97
+ end
72
98
 
73
99
  private
74
100
 
75
101
  def parse_transactions
76
- transaction_details = @xml_data.xpath('NtryDtls/TxDtls')
102
+ transaction_details = xml_data.xpath('NtryDtls/TxDtls')
77
103
 
78
104
  amt = nil
79
105
  ccy = nil
80
106
 
81
107
  if transaction_details.length == 1
82
- amt = @xml_data.xpath('Amt/text()').text
83
- ccy = @xml_data.xpath('Amt/@Ccy').text
108
+ amt = xml_data.xpath('Amt/text()').text
109
+ ccy = xml_data.xpath('Amt/@Ccy').text
84
110
  end
85
111
 
86
- @xml_data.xpath('NtryDtls/TxDtls').map { |x| Transaction.new(x, debit?, amt, ccy) }
112
+ xml_data.xpath('NtryDtls/TxDtls').map { |x| Transaction.new(x, debit?, amt, ccy) }
87
113
  end
88
-
89
114
  end
90
115
  end
@@ -2,9 +2,15 @@ require 'time'
2
2
 
3
3
  module CamtParser
4
4
  class GroupHeader
5
- attr_reader :message_id, :creation_date_time, :additional_information, :message_pagination
5
+
6
+ attr_reader :message_id,
7
+ :creation_date_time,
8
+ :additional_information,
9
+ :message_pagination,
10
+ :xml_data
6
11
 
7
12
  def initialize(xml_data)
13
+ @xml_data = xml_data
8
14
  @message_id = xml_data.xpath('MsgId/text()').text
9
15
  @creation_date_time = Time.parse(xml_data.xpath('CreDtTm/text()').text)
10
16
  @message_pagination = (x = xml_data.xpath('MsgPgntn')).empty? ? nil : MessagePagination.new(x)
@@ -13,9 +19,12 @@ module CamtParser
13
19
  end
14
20
 
15
21
  class MessagePagination
16
- attr_reader :page_number
22
+
23
+ attr_reader :page_number,
24
+ :xml_data
17
25
 
18
26
  def initialize(xml_data)
27
+ @xml_data = xml_data
19
28
  @page_number = xml_data.xpath('PgNb/text()').text.to_i
20
29
  @last_page_indicator = xml_data.xpath('LastPgInd/text()').text == 'true'
21
30
  end
@@ -1,8 +1,11 @@
1
1
  module CamtParser
2
2
  class Record
3
+
4
+ attr_reader :xml_data
5
+
3
6
  def initialize(xml_data)
4
7
  @xml_data = xml_data
5
- @amount = @xml_data.xpath('Amt/text()').text
8
+ @amount = xml_data.xpath('Amt/text()').text
6
9
  end
7
10
 
8
11
  def amount
@@ -14,19 +17,19 @@ module CamtParser
14
17
  end
15
18
 
16
19
  def currency
17
- @currency ||= @xml_data.xpath('Amt/@Ccy').text
20
+ @currency ||= xml_data.xpath('Amt/@Ccy').text
18
21
  end
19
22
 
20
23
  def type
21
- @type ||= CamtParser::Type::Builder.build_type(@xml_data.xpath('Tp'))
24
+ @type ||= CamtParser::Type::Builder.build_type(xml_data.xpath('Tp'))
22
25
  end
23
26
 
24
27
  def charges_included?
25
- @charges_included ||= @xml_data.xpath('ChrgInclInd/text()').text.downcase == 'true'
28
+ @charges_included ||= xml_data.xpath('ChrgInclInd/text()').text.downcase == 'true'
26
29
  end
27
30
 
28
31
  def debit
29
- @debit ||= @xml_data.xpath('CdtDbtInd/text()').text.upcase == 'DBIT'
32
+ @debit ||= xml_data.xpath('CdtDbtInd/text()').text.upcase == 'DBIT'
30
33
  end
31
34
 
32
35
  def credit?
@@ -1,5 +1,8 @@
1
1
  module CamtParser
2
2
  class Transaction
3
+
4
+ attr_reader :xml_data
5
+
3
6
  def initialize(xml_data, debit, amount = nil, currency = nil)
4
7
  @xml_data = xml_data
5
8
  @debit = debit
@@ -20,11 +23,11 @@ module CamtParser
20
23
  end
21
24
 
22
25
  def creditor
23
- @creditor ||= CamtParser::Creditor.new(@xml_data)
26
+ @creditor ||= CamtParser::Creditor.new(xml_data)
24
27
  end
25
28
 
26
29
  def debitor
27
- @debitor ||= CamtParser::Debitor.new(@xml_data)
30
+ @debitor ||= CamtParser::Debitor.new(xml_data)
28
31
  end
29
32
 
30
33
  def name
@@ -57,7 +60,7 @@ module CamtParser
57
60
 
58
61
  def remittance_information
59
62
  @remittance_information ||= begin
60
- if (x = @xml_data.xpath('RmtInf/Ustrd')).empty?
63
+ if (x = xml_data.xpath('RmtInf/Ustrd')).empty?
61
64
  nil
62
65
  else
63
66
  x.collect(&:content).join(' ')
@@ -66,64 +69,64 @@ module CamtParser
66
69
  end
67
70
 
68
71
  def swift_code
69
- @swift_code ||= @xml_data.xpath('BkTxCd/Prtry/Cd/text()').text.split('+')[0]
72
+ @swift_code ||= xml_data.xpath('BkTxCd/Prtry/Cd/text()').text.split('+')[0]
70
73
  end
71
74
 
72
75
  def reference
73
- @reference ||= @xml_data.xpath('Refs/InstrId/text()').text
76
+ @reference ||= xml_data.xpath('Refs/InstrId/text()').text
74
77
  end
75
78
 
76
79
  def bank_reference # May be missing
77
- @bank_reference ||= @xml_data.xpath('Refs/AcctSvcrRef/text()').text
80
+ @bank_reference ||= xml_data.xpath('Refs/AcctSvcrRef/text()').text
78
81
  end
79
82
 
80
83
  def end_to_end_reference # May be missing
81
- @end_to_end_reference ||= @xml_data.xpath('Refs/EndToEndId/text()').text
84
+ @end_to_end_reference ||= xml_data.xpath('Refs/EndToEndId/text()').text
82
85
  end
83
86
 
84
87
  def mandate_reference # May be missing
85
- @mandate_reference ||= @xml_data.xpath('Refs/MndtId/text()').text
88
+ @mandate_reference ||= xml_data.xpath('Refs/MndtId/text()').text
86
89
  end
87
90
 
88
91
  def creditor_reference # May be missing
89
- @creditor_reference ||= @xml_data.xpath('RmtInf/Strd/CdtrRefInf/Ref/text()').text
92
+ @creditor_reference ||= xml_data.xpath('RmtInf/Strd/CdtrRefInf/Ref/text()').text
90
93
  end
91
94
 
92
95
  def transaction_id # May be missing
93
- @transaction_id ||= @xml_data.xpath('Refs/TxId/text()').text
96
+ @transaction_id ||= xml_data.xpath('Refs/TxId/text()').text
94
97
  end
95
98
 
96
99
  def creditor_identifier # May be missing
97
- @creditor_identifier ||= @xml_data.xpath('RltdPties/Cdtr/Id/PrvtId/Othr/Id/text()').text
100
+ @creditor_identifier ||= xml_data.xpath('RltdPties/Cdtr/Id/PrvtId/Othr/Id/text()').text
98
101
  end
99
102
 
100
103
  def payment_information # May be missing
101
- @payment_information ||= @xml_data.xpath('Refs/PmtInfId/text()').text
104
+ @payment_information ||= xml_data.xpath('Refs/PmtInfId/text()').text
102
105
  end
103
106
 
104
107
  def additional_information # May be missing
105
- @addition_information ||= @xml_data.xpath('AddtlTxInf/text()').text
108
+ @addition_information ||= xml_data.xpath('AddtlTxInf/text()').text
106
109
  end
107
110
 
108
111
  def reason_code # May be missing
109
- @reason_code ||= @xml_data.xpath('RtrInf/Rsn/Cd/text()').text
112
+ @reason_code ||= xml_data.xpath('RtrInf/Rsn/Cd/text()').text
110
113
  end
111
114
 
112
115
  private
113
116
 
114
117
  def parse_amount
115
- if @xml_data.xpath('Amt').any?
116
- @xml_data.xpath('Amt/text()').text
117
- elsif @xml_data.xpath('AmtDtls').any?
118
- @xml_data.xpath('AmtDtls//Amt/text()').first.text
118
+ if xml_data.xpath('Amt').any?
119
+ xml_data.xpath('Amt/text()').text
120
+ elsif xml_data.xpath('AmtDtls').any?
121
+ xml_data.xpath('AmtDtls//Amt/text()').first.text
119
122
  end
120
123
  end
121
124
 
122
125
  def parse_currency
123
- if @xml_data.xpath('Amt').any?
124
- @xml_data.xpath('Amt/@Ccy').text
125
- elsif @xml_data.xpath('AmtDtls').any?
126
- @xml_data.xpath('AmtDtls//Amt/@Ccy').first.text
126
+ if xml_data.xpath('Amt').any?
127
+ xml_data.xpath('Amt/@Ccy').text
128
+ elsif xml_data.xpath('AmtDtls').any?
129
+ xml_data.xpath('AmtDtls//Amt/@Ccy').first.text
127
130
  end
128
131
  end
129
132
  end
@@ -1,6 +1,9 @@
1
1
  module CamtParser
2
2
  class Misc
3
3
  class << self
4
+
5
+ # @param value [nil, String]
6
+ # @return [Integer, nil]
4
7
  def to_amount_in_cents(value)
5
8
  return nil if value == nil || value.strip == ''
6
9
 
@@ -10,6 +13,8 @@ module CamtParser
10
13
  format('%s%s', dollars, cents.ljust(2, '0')).to_i
11
14
  end
12
15
 
16
+ # @param value [nil, String]
17
+ # @return [BigDecimal, nil]
13
18
  def to_amount(value)
14
19
  return nil if value == nil || value.strip == ''
15
20
 
@@ -7,6 +7,8 @@ CamtParser::Xml.register('urn:iso:std:iso:20022:tech:xsd:camt.052.001.02', :camt
7
7
  ## CAMT053
8
8
  CamtParser::Xml.register('urn:iso:std:iso:20022:tech:xsd:camt.053.001.02', :camt053)
9
9
  CamtParser::Xml.register('urn:iso:std:iso:20022:tech:xsd:camt.053.001.04', :camt053)
10
+ CamtParser::Xml.register('urn:iso:std:iso:20022:tech:xsd:camt.053.001.08', :camt053)
11
+ CamtParser::Xml.register('urn:iso:std:iso:20022:tech:xsd:camt.053.001.10', :camt053)
10
12
 
11
13
  ## CAMT054
12
14
  CamtParser::Xml.register('urn:iso:std:iso:20022:tech:xsd:camt.054.001.02', :camt054)
@@ -1,3 +1,3 @@
1
1
  module CamtParser
2
- VERSION = '2.14.0'.freeze
2
+ VERSION = '2.15.0'.freeze
3
3
  end
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: 2.14.0
4
+ version: 2.15.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: 2023-01-15 00:00:00.000000000 Z
11
+ date: 2023-07-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -119,7 +119,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
119
119
  - !ruby/object:Gem::Version
120
120
  version: '0'
121
121
  requirements: []
122
- rubygems_version: 3.1.6
122
+ rubygems_version: 3.4.13
123
123
  signing_key:
124
124
  specification_version: 4
125
125
  summary: Gem for parsing camt files into a speaking object.