cfonb 0.0.7 → 1.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.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/lib/cfonb/line_parser/base.rb +1 -1
  3. data/lib/cfonb/line_parser/operation.rb +1 -1
  4. data/lib/cfonb/line_parser/{operation_detail.rb → operation_details.rb} +1 -1
  5. data/lib/cfonb/operation.rb +6 -1
  6. data/lib/cfonb/operation_details/base.rb +32 -0
  7. data/lib/cfonb/operation_details/fee.rb +18 -0
  8. data/lib/cfonb/operation_details/ibe.rb +16 -0
  9. data/lib/cfonb/operation_details/ipy.rb +16 -0
  10. data/lib/cfonb/operation_details/lc2.rb +15 -0
  11. data/lib/cfonb/operation_details/lcc.rb +15 -0
  12. data/lib/cfonb/operation_details/lcs.rb +15 -0
  13. data/lib/cfonb/operation_details/lib.rb +15 -0
  14. data/lib/cfonb/operation_details/mmo.rb +26 -0
  15. data/lib/cfonb/operation_details/nbe.rb +15 -0
  16. data/lib/cfonb/operation_details/nbu.rb +15 -0
  17. data/lib/cfonb/operation_details/npo.rb +15 -0
  18. data/lib/cfonb/operation_details/npy.rb +15 -0
  19. data/lib/cfonb/operation_details/rcn.rb +18 -0
  20. data/lib/cfonb/operation_details/ref.rb +17 -0
  21. data/lib/cfonb/operation_details/unknown.rb +23 -0
  22. data/lib/cfonb/{operation_detail.rb → operation_details.rb} +5 -3
  23. data/lib/cfonb.rb +18 -12
  24. data/spec/cfonb/line_parser/{operation_detail_spec.rb → operation_details_spec.rb} +1 -1
  25. data/spec/cfonb/operation_spec.rb +120 -16
  26. data/spec/cfonb/parser_spec.rb +125 -41
  27. metadata +23 -17
  28. data/lib/cfonb/operation_detail/fee.rb +0 -18
  29. data/lib/cfonb/operation_detail/lc2.rb +0 -13
  30. data/lib/cfonb/operation_detail/lcc.rb +0 -13
  31. data/lib/cfonb/operation_detail/lcs.rb +0 -13
  32. data/lib/cfonb/operation_detail/lib.rb +0 -13
  33. data/lib/cfonb/operation_detail/mmo.rb +0 -28
  34. data/lib/cfonb/operation_detail/nbe.rb +0 -15
  35. data/lib/cfonb/operation_detail/npy.rb +0 -15
  36. data/lib/cfonb/operation_detail/rcn.rb +0 -22
  37. data/lib/cfonb/operation_detail/ref.rb +0 -20
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 92590bdbb35e07a65cd7b8dbb244a276a5efdcb05c424b0a3372f562742dc79e
4
- data.tar.gz: 73d29480cb94c937a465f31b3342ff7bc4cdb4df23a6ad9b6c47db624cdf8488
3
+ metadata.gz: 057c580fc124d3731dc852832c8c6f601584bbd235604fd5c44605b4509429c0
4
+ data.tar.gz: 037c88124d45e136b909660a8ef7f840a03fa5a7bc06c9e19e592e2eb67080a5
5
5
  SHA512:
6
- metadata.gz: 8e893921454fdfb646796d64a0cf0d1a1150488ccf73952d23e55db36d2d5e7551eab014550006195cbde4c2915aa52e6a50253605d98d2f1edc3871baf58ed1
7
- data.tar.gz: a44a4b448a3bcb560bd0f4bc61dbd7beb1bf5083ffcb72be1862546af6d0f59dd549e758e796f0e3ff5e6915b94e46ac4fb3fa0b2c1d3f4c81f9c9f28cb263e0
6
+ metadata.gz: b803bf7c0a2c0803e7ae54ea937d3ccb06eeeced3f7dcc033ce202a658137c41da085adf462c2ebcf9d76352cb3990467a45deeaf0a80ad6c86b713a9733248e
7
+ data.tar.gz: 02c6b90c2732f5da3b481ec2c9b811b17377d0a7e602780d2048baf86499c3115abe4fcff98cd1cf454a80967565167aa6475fd53cc8442e43c14ddad79d89a4
@@ -12,7 +12,7 @@ module CFONB
12
12
  ['bank', (2..6)],
13
13
  ['branch', (11..15)],
14
14
  ['currency', (16..18)],
15
- ['scale', 19, proc { _1.to_i }],
15
+ ['scale', 19, proc { _1.to_i }], # rubocop:disable Style/SymbolProc
16
16
  ['account', (21..31)],
17
17
  ['date', (34..39), proc { |value, instance| instance.send(:parse_date, value) }],
18
18
  ].freeze
@@ -9,7 +9,7 @@ module CFONB
9
9
  ['rejection_code', (40..41)],
10
10
  ['value_date', (42..47), proc { |value, instance| instance.send(:parse_date, value) }],
11
11
  ['label', (48..79)],
12
- ['number', (81..87), proc { _1.to_i }],
12
+ ['number', (81..87), proc { _1.to_i }], # rubocop:disable Style/SymbolProc
13
13
  ['exoneration_code', 88],
14
14
  ['unavailability_code', 89],
15
15
  ['reference', (104..119)],
@@ -2,7 +2,7 @@
2
2
 
3
3
  module CFONB
4
4
  module LineParser
5
- class OperationDetail < Base
5
+ class OperationDetails < Base
6
6
  DICTIONARY = [
7
7
  ['internal_operation_code', (7..10)],
8
8
  ['interbank_operation_code', (32..33)],
@@ -1,6 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module CFONB
4
+ Details = Class.new
5
+
4
6
  class Operation
5
7
  BASE_ATTRIBUTES = %i[
6
8
  raw
@@ -16,6 +18,7 @@ module CFONB
16
18
  rejection_code
17
19
  unavailability_code
18
20
  value_date
21
+ details
19
22
  ].freeze
20
23
 
21
24
  attr_accessor(*BASE_ATTRIBUTES)
@@ -34,11 +37,13 @@ module CFONB
34
37
  self.label = line.label.strip
35
38
  self.number = line.number
36
39
  self.reference = line.reference
40
+ self.details = Details.new
37
41
  end
38
42
 
39
43
  def merge_detail(line)
40
44
  self.raw += "\n#{line.body}"
41
- OperationDetail.for(line)&.apply(self, line)
45
+
46
+ OperationDetails.for(line)&.apply(details, line)
42
47
  end
43
48
 
44
49
  def type_code
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CFONB
4
+ module OperationDetails
5
+ class Base
6
+ def self.inherited(base)
7
+ base.singleton_class.prepend(
8
+ Module.new do
9
+ def apply(details, line)
10
+ code = :"@#{line.detail_code}"
11
+ details.instance_variable_set(code, instance_value(details, line, code))
12
+
13
+ super
14
+ end
15
+
16
+ private
17
+
18
+ def append_detail?(details, line, code)
19
+ details.instance_variable_defined?(code) && line.detail.is_a?(String)
20
+ end
21
+
22
+ def instance_value(details, line, code)
23
+ return line.detail unless append_detail?(details, line, code)
24
+
25
+ details.instance_variable_get(code) + "\n#{line.detail}"
26
+ end
27
+ end,
28
+ )
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CFONB
4
+ module OperationDetails
5
+ class FEE < Base
6
+ ATTRIBUTES = %i[fee fee_currency].freeze
7
+
8
+ def self.apply(details, line)
9
+ details.fee_currency = line.detail[0..2]
10
+ scale = line.detail[3].to_i
11
+
12
+ details.fee = BigDecimal(line.detail[4..17]) / (10**scale)
13
+ end
14
+
15
+ CFONB::OperationDetails.register('FEE', self)
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CFONB
4
+ module OperationDetails
5
+ class IBE < Base
6
+ ATTRIBUTES = %i[creditor_identifier creditor_identifier_type].freeze
7
+
8
+ def self.apply(details, line)
9
+ details.creditor_identifier = line.detail[0..34].strip
10
+ details.creditor_identifier_type = line.detail[35..-1]&.strip
11
+ end
12
+
13
+ CFONB::OperationDetails.register('IBE', self)
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CFONB
4
+ module OperationDetails
5
+ class IPY < Base
6
+ ATTRIBUTES = %i[debtor_identifier debtor_identifier_type].freeze
7
+
8
+ def self.apply(details, line)
9
+ details.debtor_identifier = line.detail[0..34].strip
10
+ details.debtor_identifier_type = line.detail[35..-1]&.strip
11
+ end
12
+
13
+ CFONB::OperationDetails.register('IPY', self)
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CFONB
4
+ module OperationDetails
5
+ class LC2 < Base
6
+ ATTRIBUTES = %i[unstructured_label_2].freeze
7
+
8
+ def self.apply(details, line)
9
+ details.unstructured_label_2 = line.detail.strip
10
+ end
11
+
12
+ CFONB::OperationDetails.register('LC2', self)
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CFONB
4
+ module OperationDetails
5
+ class LCC < Base
6
+ ATTRIBUTES = %i[unstructured_label].freeze
7
+
8
+ def self.apply(details, line)
9
+ details.unstructured_label = line.detail.strip.to_s
10
+ end
11
+
12
+ CFONB::OperationDetails.register('LCC', self)
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CFONB
4
+ module OperationDetails
5
+ class LCS < Base
6
+ ATTRIBUTES = %i[structured_label].freeze
7
+
8
+ def self.apply(details, line)
9
+ details.structured_label = line.detail[0..35].strip
10
+ end
11
+
12
+ CFONB::OperationDetails.register('LCS', self)
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CFONB
4
+ module OperationDetails
5
+ class LIB < Base
6
+ ATTRIBUTES = %i[free_label].freeze
7
+
8
+ def self.apply(details, line)
9
+ details.free_label = [details.free_label, line.detail.strip].compact.join("\n")
10
+ end
11
+
12
+ CFONB::OperationDetails.register('LIB', self)
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bigdecimal'
4
+
5
+ module CFONB
6
+ module OperationDetails
7
+ class MMO < Base
8
+ ATTRIBUTES = %i[original_currency original_amount exchange_rate].freeze
9
+
10
+ def self.apply(details, line)
11
+ details.original_currency = line.detail[0..2]
12
+ scale = line.detail[3].to_i
13
+
14
+ details.original_amount = BigDecimal(line.detail[4..17]) / (10**scale)
15
+ exchange_rate_value = line.detail[26..29]
16
+
17
+ return if exchange_rate_value.nil? || exchange_rate_value.strip.empty?
18
+
19
+ exchange_rate_scale = line.detail[18]
20
+ details.exchange_rate = BigDecimal(exchange_rate_value) / (10**BigDecimal(exchange_rate_scale))
21
+ end
22
+
23
+ CFONB::OperationDetails.register('MMO', self)
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CFONB
4
+ module OperationDetails
5
+ class NBE < Base
6
+ ATTRIBUTES = %i[creditor].freeze
7
+
8
+ def self.apply(details, line)
9
+ details.creditor = line.detail.strip
10
+ end
11
+
12
+ CFONB::OperationDetails.register('NBE', self)
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CFONB
4
+ module OperationDetails
5
+ class NBU < Base
6
+ ATTRIBUTES = %i[ultimate_creditor].freeze
7
+
8
+ def self.apply(details, line)
9
+ details.ultimate_creditor = line.detail.strip
10
+ end
11
+
12
+ CFONB::OperationDetails.register('NBU', self)
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CFONB
4
+ module OperationDetails
5
+ class NPO < Base
6
+ ATTRIBUTES = %i[ultimate_debtor].freeze
7
+
8
+ def self.apply(details, line)
9
+ details.ultimate_debtor = line.detail.strip
10
+ end
11
+
12
+ CFONB::OperationDetails.register('NPO', self)
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CFONB
4
+ module OperationDetails
5
+ class NPY < Base
6
+ ATTRIBUTES = %i[debtor].freeze
7
+
8
+ def self.apply(details, line)
9
+ details.debtor = line.detail.strip
10
+ end
11
+
12
+ CFONB::OperationDetails.register('NPY', self)
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CFONB
4
+ module OperationDetails
5
+ class RCN < Base
6
+ using CFONB::Refinements::Strings
7
+
8
+ ATTRIBUTES = %i[client_reference purpose].freeze
9
+
10
+ def self.apply(details, line)
11
+ details.client_reference = line.detail[0..34].strip
12
+ details.purpose = line.detail[35..-1]&.strip
13
+ end
14
+
15
+ CFONB::OperationDetails.register('RCN', self)
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CFONB
4
+ module OperationDetails
5
+ class REF < Base
6
+ using CFONB::Refinements::Strings
7
+
8
+ ATTRIBUTES = %i[operation_reference].freeze
9
+
10
+ def self.apply(details, line)
11
+ details.operation_reference = line.detail.strip
12
+ end
13
+
14
+ CFONB::OperationDetails.register('REF', self)
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CFONB
4
+ module OperationDetails
5
+ class Unknown < Base
6
+ ATTRIBUTES = %i[unknown].freeze
7
+
8
+ def self.apply(details, line)
9
+ details.unknown ||= {}
10
+ code = line.detail_code
11
+
12
+ details.unknown[code] =
13
+ if details.unknown[code] && line.detail.is_a?(String)
14
+ details.unknown[code] + "\n#{line.detail}"
15
+ else
16
+ line.detail
17
+ end
18
+ end
19
+
20
+ CFONB::OperationDetails.register('Unknown', self)
21
+ end
22
+ end
23
+ end
@@ -1,12 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module CFONB
4
- module OperationDetail
4
+ module OperationDetails
5
5
  @details = {}
6
6
 
7
7
  def self.register(code, klass)
8
8
  if klass.const_defined?(:ATTRIBUTES)
9
- Operation.class_eval do
9
+ CFONB::Details.class_eval do
10
10
  attr_accessor(*klass::ATTRIBUTES)
11
11
  end
12
12
  end
@@ -15,7 +15,9 @@ module CFONB
15
15
  end
16
16
 
17
17
  def self.for(line)
18
- @details[line.detail_code]
18
+ return unless line.respond_to?(:detail_code)
19
+
20
+ @details[line.detail_code] || Unknown
19
21
  end
20
22
  end
21
23
  end
data/lib/cfonb.rb CHANGED
@@ -8,25 +8,31 @@ require_relative 'cfonb/error'
8
8
  require_relative 'cfonb/parser'
9
9
  require_relative 'cfonb/statement'
10
10
  require_relative 'cfonb/operation'
11
- require_relative 'cfonb/operation_detail'
11
+ require_relative 'cfonb/operation_details'
12
12
 
13
13
  require_relative 'cfonb/line_parser'
14
14
  require_relative 'cfonb/line_parser/base'
15
15
  require_relative 'cfonb/line_parser/previous_balance'
16
16
  require_relative 'cfonb/line_parser/operation'
17
- require_relative 'cfonb/line_parser/operation_detail'
17
+ require_relative 'cfonb/line_parser/operation_details'
18
18
  require_relative 'cfonb/line_parser/new_balance'
19
19
 
20
- require_relative 'cfonb/operation_detail/lib'
21
- require_relative 'cfonb/operation_detail/lcc'
22
- require_relative 'cfonb/operation_detail/lc2'
23
- require_relative 'cfonb/operation_detail/lcs'
24
- require_relative 'cfonb/operation_detail/mmo'
25
- require_relative 'cfonb/operation_detail/nbe'
26
- require_relative 'cfonb/operation_detail/npy'
27
- require_relative 'cfonb/operation_detail/rcn'
28
- require_relative 'cfonb/operation_detail/ref'
29
- require_relative 'cfonb/operation_detail/fee'
20
+ require_relative 'cfonb/operation_details/base'
21
+ require_relative 'cfonb/operation_details/lib'
22
+ require_relative 'cfonb/operation_details/lcc'
23
+ require_relative 'cfonb/operation_details/lc2'
24
+ require_relative 'cfonb/operation_details/lcs'
25
+ require_relative 'cfonb/operation_details/mmo'
26
+ require_relative 'cfonb/operation_details/nbe'
27
+ require_relative 'cfonb/operation_details/npy'
28
+ require_relative 'cfonb/operation_details/ipy'
29
+ require_relative 'cfonb/operation_details/rcn'
30
+ require_relative 'cfonb/operation_details/ref'
31
+ require_relative 'cfonb/operation_details/fee'
32
+ require_relative 'cfonb/operation_details/ibe'
33
+ require_relative 'cfonb/operation_details/npo'
34
+ require_relative 'cfonb/operation_details/nbu'
35
+ require_relative 'cfonb/operation_details/unknown'
30
36
 
31
37
  module CFONB
32
38
  def self.parse(input, optimistic: false)
@@ -2,7 +2,7 @@
2
2
 
3
3
  require 'cfonb'
4
4
 
5
- describe CFONB::LineParser::OperationDetail do
5
+ describe CFONB::LineParser::OperationDetails do
6
6
  describe '.initialize' do
7
7
  subject(:line) { described_class.new(input) }
8
8