cfonb 0.0.7 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
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