diff --git a/Gemfile.lock b/Gemfile.lock index 3288f10..3f9d425 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: . specs: - sepa_file_parser (0.1.0) + sepa_file_parser (0.2.0) bigdecimal nokogiri time diff --git a/lib/sepa_file_parser.rb b/lib/sepa_file_parser.rb index 4a3a8cd..6234652 100644 --- a/lib/sepa_file_parser.rb +++ b/lib/sepa_file_parser.rb @@ -30,6 +30,8 @@ require_relative 'sepa_file_parser/camt054/base' require_relative 'sepa_file_parser/pain001/payment_information' require_relative 'sepa_file_parser/pain001/base' +require_relative 'sepa_file_parser/pain002/report' +require_relative 'sepa_file_parser/pain002/base' require_relative 'sepa_file_parser/pain008/payment_information' require_relative 'sepa_file_parser/pain008/base' require_relative 'sepa_file_parser/file' diff --git a/lib/sepa_file_parser/pain002/base.rb b/lib/sepa_file_parser/pain002/base.rb new file mode 100644 index 0000000..d49c19f --- /dev/null +++ b/lib/sepa_file_parser/pain002/base.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +module SepaFileParser + module Pain002 + class Base + attr_reader :group_header, :reports, :xml_data + + def initialize(xml_data) + @xml_data = xml_data + # CstmrPmtStsRpt = Customer Payment Status Report + grphdr = xml_data.xpath('CstmrPmtStsRpt/GrpHdr') + @group_header = SepaFileParser::GroupHeader.new(grphdr) + reports = xml_data.xpath('CstmrPmtStsRpt/OrgnlPmtInfAndSts') + @reports = reports.map { |x| Report.new(x) } + end + end + end +end diff --git a/lib/sepa_file_parser/pain002/report.rb b/lib/sepa_file_parser/pain002/report.rb new file mode 100644 index 0000000..09ccb23 --- /dev/null +++ b/lib/sepa_file_parser/pain002/report.rb @@ -0,0 +1,31 @@ +# frozen_string_literal: true + +module SepaFileParser + module Pain002 + class Report + + attr_reader :xml_data + + def initialize(xml_data) + @xml_data = xml_data + end + + def original_identification + @original_identification ||= xml_data.xpath('OrgnlPmtInfId/text()').text + end + + def status_id + @status_id ||= xml_data.xpath('TxInfAndSts/StsId/text()').text + end + + def transaction_status + @transaction_status ||= xml_data.xpath('TxInfAndSts/TxSts/text()').text + end + + def source + xml_data.to_s + end + + end + end +end diff --git a/lib/sepa_file_parser/register.rb b/lib/sepa_file_parser/register.rb index 52cb406..8369967 100644 --- a/lib/sepa_file_parser/register.rb +++ b/lib/sepa_file_parser/register.rb @@ -19,5 +19,8 @@ ## PAIN001 SepaFileParser::Xml.register('urn:iso:std:iso:20022:tech:xsd:pain.001.001.03', :pain001) +## PAIN002 +SepaFileParser::Xml.register('urn:iso:std:iso:20022:tech:xsd:pain.002.001.03', :pain002) + ## PAIN008 SepaFileParser::Xml.register('urn:iso:std:iso:20022:tech:xsd:pain.008.003.02', :pain008) diff --git a/lib/sepa_file_parser/version.rb b/lib/sepa_file_parser/version.rb index add27af..a730041 100644 --- a/lib/sepa_file_parser/version.rb +++ b/lib/sepa_file_parser/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module SepaFileParser - VERSION = '0.1.0'.freeze + VERSION = '0.2.0'.freeze end diff --git a/lib/sepa_file_parser/xml.rb b/lib/sepa_file_parser/xml.rb index a08b276..d7afc40 100644 --- a/lib/sepa_file_parser/xml.rb +++ b/lib/sepa_file_parser/xml.rb @@ -7,6 +7,7 @@ class Xml camt053: SepaFileParser::Camt053::Base, camt054: SepaFileParser::Camt054::Base, pain001: SepaFileParser::Pain001::Base, + pain002: SepaFileParser::Pain002::Base, pain008: SepaFileParser::Pain008::Base, }.freeze diff --git a/spec/fixtures/pain002/valid_example.xml b/spec/fixtures/pain002/valid_example.xml new file mode 100644 index 0000000..e177b3b --- /dev/null +++ b/spec/fixtures/pain002/valid_example.xml @@ -0,0 +1,101 @@ + + + + + Message-ID-12346 + 2024-05-22T09:30:47.000Z + + + KKKKDEFFXXX + + + + + Message-ID-12345 + pain.008 + + + Payment-Information-ID-12345 + + Status-ID + Source1234 + RJCT + + + + + KKKKDEFFXXX + + + + + AC01 + + + + + 6543.14 + + 2024-05-03 + + + + + DE99ZZZ100001234567 + + SEPA + + + + + + + + SEPA + + + CORE + + FRST + + + Mandate-Id + 2024-05-20 + + + Unstructured Remittance Information + + + Ultimate Debtor Name + + + Debtor Name + + + + DE89370400440532013000 + + + + + COBADEFFXXX + + + + + COBADEFFXXX + + + + Creditor Name + + + + DE75512108001245126199 + + + + + + + diff --git a/spec/lib/sepa_file_parser/pain002/base_spec.rb b/spec/lib/sepa_file_parser/pain002/base_spec.rb new file mode 100644 index 0000000..44b77f3 --- /dev/null +++ b/spec/lib/sepa_file_parser/pain002/base_spec.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe SepaFileParser::Pain002::Base do + + context 'initialization' do + after do + SepaFileParser::File.parse 'spec/fixtures/pain002/valid_example.xml' + end + + specify { expect(SepaFileParser::GroupHeader).to receive(:new).and_call_original } + specify do + expect(SepaFileParser::Pain002::Report).to receive(:new).and_call_original + end + end + + let(:pain) { SepaFileParser::File.parse 'spec/fixtures/pain002/valid_example.xml' } + specify { expect(pain.group_header).to_not be_nil } + specify { expect(pain.reports).to_not eq([]) } + specify { expect(pain.xml_data).to_not be_nil } + +end diff --git a/spec/lib/sepa_file_parser/pain002/report_spec.rb b/spec/lib/sepa_file_parser/pain002/report_spec.rb new file mode 100644 index 0000000..a2f1ade --- /dev/null +++ b/spec/lib/sepa_file_parser/pain002/report_spec.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe SepaFileParser::Pain002::Report do + let(:pain) { SepaFileParser::File.parse('spec/fixtures/pain002/valid_example.xml') } + + let(:reports) { pain.reports } + let(:ex_report) { pain.reports[0] } + let(:entry) { ex_report.entries[0] } + + specify { expect(reports).to all(be_kind_of(described_class)) } + specify { expect(ex_report.original_identification).to eq('Payment-Information-ID-12345') } + specify { expect(ex_report.status_id).to eq('Status-ID') } + specify { expect(ex_report.transaction_status).to eq('RJCT') } + + specify { expect(pain.xml_data.nil?).to eq(false) } +end