From d9cb64ad3fae79e8e62025745085022b6bd47e88 Mon Sep 17 00:00:00 2001 From: Joana Bertoldi Date: Thu, 28 Nov 2024 18:27:40 +0000 Subject: [PATCH] Return unmapped operation_details in "details.unknown" object --- README.md | 3 ++- cfonb.gemspec | 2 +- lib/cfonb.rb | 1 + lib/cfonb/operation_details.rb | 4 +++- lib/cfonb/operation_details/unknown.rb | 23 +++++++++++++++++++++++ spec/cfonb/operation_spec.rb | 23 +++++++++++++++++++++++ spec/cfonb/parser_spec.rb | 5 +++++ spec/files/example.txt | 4 ++++ 8 files changed, 62 insertions(+), 3 deletions(-) create mode 100644 lib/cfonb/operation_details/unknown.rb diff --git a/README.md b/README.md index f2e8878..caa1d4b 100644 --- a/README.md +++ b/README.md @@ -33,8 +33,9 @@ gem 'cfonb' Below is the list of additional details available for each operation. These details can be accessed through `operation.details`, which will provide all the attributes. To fetch a specific attribute, you can use `operation.details.attribute`. For example, `operation.details.unstructured_label`. Ultimately, you can also access the 70 characters of the detail by using its code like `operation.details.mmo` +All unmapped details can be accessed via `details.unknown` which will return the codes and the corresponding line details. -If you encounter new ones, please open an issue or a pull request with the appropriate implementation. +If you encounter new and relevant ones, please open an issue or a pull request with the appropriate implementation. We aimed at making it as easy as possible to add new details. You just need to do the following on initialization: ```ruby diff --git a/cfonb.gemspec b/cfonb.gemspec index 9949e72..6750406 100644 --- a/cfonb.gemspec +++ b/cfonb.gemspec @@ -2,7 +2,7 @@ Gem::Specification.new do |s| s.name = 'cfonb' - s.version = '1.0.0' + s.version = '1.1.0' s.required_ruby_version = '>= 3.2' s.summary = 'CFONB parser' s.description = 'An easy to use CFONB format parser' diff --git a/lib/cfonb.rb b/lib/cfonb.rb index 24c7d6d..e7be641 100644 --- a/lib/cfonb.rb +++ b/lib/cfonb.rb @@ -32,6 +32,7 @@ require_relative 'cfonb/operation_details/ibe' require_relative 'cfonb/operation_details/npo' require_relative 'cfonb/operation_details/nbu' +require_relative 'cfonb/operation_details/unknown' module CFONB def self.parse(input, optimistic: false) diff --git a/lib/cfonb/operation_details.rb b/lib/cfonb/operation_details.rb index f9bde87..8e06f2b 100644 --- a/lib/cfonb/operation_details.rb +++ b/lib/cfonb/operation_details.rb @@ -15,7 +15,9 @@ def self.register(code, klass) end def self.for(line) - @details[line.detail_code] + return unless line.respond_to?(:detail_code) + + @details[line.detail_code] || Unknown end end end diff --git a/lib/cfonb/operation_details/unknown.rb b/lib/cfonb/operation_details/unknown.rb new file mode 100644 index 0000000..46b3624 --- /dev/null +++ b/lib/cfonb/operation_details/unknown.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +module CFONB + module OperationDetails + class Unknown < Base + ATTRIBUTES = %i[unknown].freeze + + def self.apply(details, line) + details.unknown ||= {} + code = line.detail_code + + details.unknown[code] = + if details.unknown[code] && line.detail.is_a?(String) + details.unknown[code] + "\n#{line.detail}" + else + line.detail + end + end + + CFONB::OperationDetails.register('Unknown', self) + end + end +end diff --git a/spec/cfonb/operation_spec.rb b/spec/cfonb/operation_spec.rb index d31a56f..2aff10a 100644 --- a/spec/cfonb/operation_spec.rb +++ b/spec/cfonb/operation_spec.rb @@ -272,6 +272,29 @@ expect(operation.details.ultimate_creditor).to eq('Patrick') end end + + context 'with an unknown detail' do + let(:detail) do + OpenStruct.new( + body: '0530004411001871EUR2 0001016255614090823 AAAEUR200000000000740', + detail_code: 'AAA', + detail: 'EUR200000000000740', + ) + end + + it 'adds the detail to the unknown details hash' do + operation.merge_detail(detail) + + expect(operation.details.unknown).to eq({ 'AAA' => 'EUR200000000000740' }) + end + + it 'updates the current details in case of duplicated codes' do + operation.merge_detail(detail) + operation.merge_detail(detail) + + expect(operation.details.unknown).to eq({ 'AAA' => "EUR200000000000740\nEUR200000000000740" }) + end + end end describe '#type_code' do diff --git a/spec/cfonb/parser_spec.rb b/spec/cfonb/parser_spec.rb index 694847d..2e95437 100644 --- a/spec/cfonb/parser_spec.rb +++ b/spec/cfonb/parser_spec.rb @@ -49,6 +49,11 @@ exchange_rate: nil, purpose: 'PURPOSE', debtor: 'INTERNET SFR', + unknown: { + 'AAA' => "INTERNETA AAA\nINTERNETA ABB", + 'BBB' => 'INTERNETE BBB', + 'CCC' => 'INTERNETI CCC', + }, ) expect(statements[0].operations[1]).to have_attributes( diff --git a/spec/files/example.txt b/spec/files/example.txt index 21e21d3..c8d728e 100644 --- a/spec/files/example.txt +++ b/spec/files/example.txt @@ -6,6 +6,10 @@ 0515589916200000EUR2 98765432100B1160519 REFREFERENCE 0515589916200000EUR2 98765432100B1160519 RCNOTHER REFERENCE PURPOSE 0515589916200000EUR2 98765432100B1160519 NPYINTERNET SFR +0515589916200000EUR2 98765432100B1160519 AAAINTERNETA AAA +0515589916200000EUR2 98765432100B1160519 AAAINTERNETA ABB +0515589916200000EUR2 98765432100B1160519 BBBINTERNETE BBB +0515589916200000EUR2 98765432100B1160519 CCCINTERNETI CCC 0415589916200000EUR2 98765432100B1160519 160519VIR SEPA DEMONSTRATION 0000000000000000000107}REFERENCE 0515589916200000EUR2 98765432100B1160519 NPYELEC ERDF