From c44da3853ea49b01e57ba3ea2e9a39f183a53c4f Mon Sep 17 00:00:00 2001 From: Joana Bertoldi Date: Thu, 28 Nov 2024 13:23:39 +0000 Subject: [PATCH] Ensure duplicated code details persistence on operation details --- lib/cfonb.rb | 1 + lib/cfonb/operation_details/base.rb | 33 ++++++++++++++++++++++++++++- lib/cfonb/operation_details/lib.rb | 2 +- lib/cfonb/refinements/arrays.rb | 15 +++++++++++++ spec/cfonb/parser_spec.rb | 12 +++++------ spec/files/example.txt | 1 + 6 files changed, 56 insertions(+), 8 deletions(-) create mode 100644 lib/cfonb/refinements/arrays.rb diff --git a/lib/cfonb.rb b/lib/cfonb.rb index 24c7d6d..ab7e826 100644 --- a/lib/cfonb.rb +++ b/lib/cfonb.rb @@ -3,6 +3,7 @@ require 'date' require_relative 'cfonb/refinements/strings' +require_relative 'cfonb/refinements/arrays' require_relative 'cfonb/error' require_relative 'cfonb/parser' diff --git a/lib/cfonb/operation_details/base.rb b/lib/cfonb/operation_details/base.rb index 5c80a98..dcfc7b9 100644 --- a/lib/cfonb/operation_details/base.rb +++ b/lib/cfonb/operation_details/base.rb @@ -3,13 +3,42 @@ module CFONB module OperationDetails class Base + using CFONB::Refinements::Arrays + def self.inherited(base) base.singleton_class.prepend( Module.new do def apply(details, line) - details.instance_variable_set(:"@#{line.detail_code}", line.detail) + return unless line.respond_to?(:detail) + + current_details = attributes.map { |attribute| [attribute, details.send(attribute)] }.to_h + current_instance = details.instance_variable_get(:"@#{line.detail_code}") + new_instance = merge_details(current_instance, line.detail) + + details.instance_variable_set(:"@#{line.detail_code}", new_instance) super + + include_duplicated_code_details(current_details, details) + end + + def merge_details(existing_detail, new_detail) + [existing_detail, new_detail].join_sanitized + end + + private + + def attributes + const_get(:ATTRIBUTES) + end + + def include_duplicated_code_details(existing_details, details) + attributes.each do |attribute| + details.send( + "#{attribute}=", + merge_details(existing_details[attribute], details.send(attribute)), + ) + end end end, ) @@ -17,3 +46,5 @@ def apply(details, line) end end end + +# return if attributes.include?(:unknown) diff --git a/lib/cfonb/operation_details/lib.rb b/lib/cfonb/operation_details/lib.rb index cbf92a9..2d73541 100644 --- a/lib/cfonb/operation_details/lib.rb +++ b/lib/cfonb/operation_details/lib.rb @@ -6,7 +6,7 @@ class LIB < Base ATTRIBUTES = %i[free_label].freeze def self.apply(details, line) - details.free_label = [details.free_label, line.detail.strip].compact.join("\n") + details.free_label = line.detail end CFONB::OperationDetails.register('LIB', self) diff --git a/lib/cfonb/refinements/arrays.rb b/lib/cfonb/refinements/arrays.rb new file mode 100644 index 0000000..eafc6d7 --- /dev/null +++ b/lib/cfonb/refinements/arrays.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +module CFONB + module Refinements + module Arrays + refine Array do + def join_sanitized + return last unless last.is_a?(String) + + compact.map(&:strip).join("\n") + end + end + end + end +end diff --git a/spec/cfonb/parser_spec.rb b/spec/cfonb/parser_spec.rb index a6fb0eb..9925c6b 100644 --- a/spec/cfonb/parser_spec.rb +++ b/spec/cfonb/parser_spec.rb @@ -43,7 +43,7 @@ reference: '', ) expect(statements[0].operations[0].details).to have_attributes( - free_label: 'MENSUEAUHTR13133', + free_label: "MENSUEAUHTR13133\nMENSUEAUHTR13DUP", original_currency: nil, original_amount: nil, exchange_rate: nil, @@ -272,7 +272,7 @@ expect(statements[0].operations[0].details).to have_attributes( operation_reference: 'REFERENCE', - free_label: 'MENSUEAUHTR13133', + free_label: "MENSUEAUHTR13133\nMENSUEAUHTR13DUP", debtor: 'INTERNET SFR', client_reference: 'OTHER REFERENCE', original_currency: nil, @@ -684,10 +684,10 @@ end end - context 'with an unhandled line code' do + context 'with a duplicated line code' do let(:input) { File.read('spec/files/example.txt') } - it 'ignores the unhandled lines' do + it 'concatenates the duplicated line' do expect(operation).to have_attributes( amount: -32.21, currency: 'EUR', @@ -705,8 +705,8 @@ expect(operation.details).to have_attributes( operation_reference: 'REFERENCE', client_reference: 'OTHER REFERENCE', - free_label: "MENSUEAUHTR13133\nP051928612 22793301700040", - debtor: 'ELEC ERDF', + free_label: "MENSUEAUHTR13133\nMENSUEAUHTR13DUP\nP051928612 22793301700040", + debtor: "INTERNET SFR\nELEC ERDF", original_currency: nil, original_amount: nil, exchange_rate: nil, diff --git a/spec/files/example.txt b/spec/files/example.txt index 5bb62e0..21e21d3 100644 --- a/spec/files/example.txt +++ b/spec/files/example.txt @@ -2,6 +2,7 @@ 0415589916200000EUR2 98765432100B1160519 160519PRLV SEPA TEST CABINET 0000000000000000000322J 0515589916200000EUR2 98765432100B1160519 LIBMENSUEAUHTR13133 +0515589916200000EUR2 98765432100B1160519 LIBMENSUEAUHTR13DUP 0515589916200000EUR2 98765432100B1160519 REFREFERENCE 0515589916200000EUR2 98765432100B1160519 RCNOTHER REFERENCE PURPOSE 0515589916200000EUR2 98765432100B1160519 NPYINTERNET SFR