Skip to content

Commit

Permalink
Lg/breaking changes (#25)
Browse files Browse the repository at this point in the history
Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: RDeckard <[email protected]>
  • Loading branch information
3 people authored Nov 12, 2024
1 parent 0cfe429 commit b6fef0c
Show file tree
Hide file tree
Showing 21 changed files with 227 additions and 134 deletions.
41 changes: 20 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,38 +30,37 @@ gem 'cfonb'
## Available Operation Details

`OperationDetails` are lines starting with `05`. They aim at providing additional information about the operation.
Below is the list of additional details available for each operation.

Find bellow the list of additional details available for each operation.
If you encouter new ones, please open an issue or a pull request with the appropriate implementation.
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`

If you encounter new 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
CFONB::OperationDetails.register('FEE', self)
```

| Detail Code | Attributes | Description |
| ----------- | --------------------------------------------------------------------------------------- | -------------------------------------------------------------------- |
| FEE | `fee`, `fee_currency` | Represents operation fees the bank is applying |
| LCC | `unstructured_label` | Not structured label line 1 (first 70 characters) |
| LC2 | `unstructured_label_2` | Not structured label line 2 (last 70 characters) |
| LCS | `structured_label` | Structured label |
| LIB | `free_label` | Free label |
| MMO | `original_currency`, `original_amount`, `scale`, `exchange_rate`, `exchange_rate_scale` | Amount and currency if it has been converted from a foreign currency |
| NBE | `creditor` | Name of the creditor or beneficiary |
| NPY | `debtor` | Name of the debtor or payer |
| RCN | `reference`, `purpose` | Client reference and Payment nature/purpose |
| REF | `operation_reference` | Bank operation reference |
| IPY | `debtor_identifier`, `debtor_identifier_type` | Debtor identifier and debtor identifier type |
| IBE | `creditor_identifier`, `creditor_identifier_type` | Creditor identifier and the type of identifier |
| NPO | `ultimate_debtor` | Name of the ultimate debtor or beneficiary |
| NBU | `ultimate_creditor` | Name of the ultimate creditor or payer |
| Detail Code | Attributes | Description |
| ----------- | ------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
| FEE | `fee`, `fee_currency` | Represents operation fees the bank is applying |
| IPY | `debtor_identifier`, `debtor_identifier_type` | Debtor identifier and debtor identifier type |
| IBE | `creditor_identifier`, `creditor_identifier_type` | Creditor identifier and the type of identifier |
| LC2 | `unstructured_label_2` | Not structured label line 2 (last 70 characters) |
| LCC | `unstructured_label` | Not structured label line 1 (first 70 characters) |
| LCS | `structured_label` | Structured label |
| LIB | `free_label` | Free label |
| MMO | `original_currency`, `original_amount`, `exchange_rate` | Amount and currency if it has been converted from a foreign currency. The `original_amount` is unsigned, meaning it is always non-negative. |
| NBE | `creditor` | Name of the creditor or beneficiary |
| NBU | `ultimate_creditor` | Name of the ultimate creditor or payer |
| NPO | `ultimate_debtor` | Name of the ultimate debtor or beneficiary |
| NPY | `debtor` | Name of the debtor or payer |
| RCN | `client_reference`, `purpose` | Client reference and Payment nature/purpose |
| REF | `operation_reference` | Bank operation reference |

TODO:
| Detail Code | Attributes | Description |
| --- | --- | --- |
| IPY | `debtor_identifier` | Identifier of the debtor or payer |
| NPO | `ultimate_debtor` | Name of the ultimate debtor or beneficiary |
| NBU | `ultimate_creditor` | Name of the ultimate creditor or payer |
| RET | `unifi_code`, `sit_code`, `payback_label` | Payback informations |
| CBE | `creditor_account` | Account of the creditor or beneficiary |
| BDB | `creditor_bank` | Bank of the creditor or beneficiary |
Expand Down
2 changes: 1 addition & 1 deletion cfonb.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

Gem::Specification.new do |s|
s.name = 'cfonb'
s.version = '0.0.7'
s.version = '1.0.0'
s.required_ruby_version = '>= 3.2'
s.summary = 'CFONB parser'
s.description = 'An easy to use CFONB format parser'
Expand Down
7 changes: 6 additions & 1 deletion lib/cfonb/operation.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# frozen_string_literal: true

module CFONB
Details = Class.new

class Operation
BASE_ATTRIBUTES = %i[
raw
Expand All @@ -16,6 +18,7 @@ class Operation
rejection_code
unavailability_code
value_date
details
].freeze

attr_accessor(*BASE_ATTRIBUTES)
Expand All @@ -34,11 +37,13 @@ def initialize(line)
self.label = line.label.strip
self.number = line.number
self.reference = line.reference
self.details = Details.new
end

def merge_detail(line)
self.raw += "\n#{line.body}"
OperationDetails.for(line)&.apply(self, line)

OperationDetails.for(line)&.apply(details, line)
end

def type_code
Expand Down
2 changes: 1 addition & 1 deletion lib/cfonb/operation_details.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ module OperationDetails

def self.register(code, klass)
if klass.const_defined?(:ATTRIBUTES)
Operation.class_eval do
CFONB::Details.class_eval do
attr_accessor(*klass::ATTRIBUTES)
end
end
Expand Down
4 changes: 2 additions & 2 deletions lib/cfonb/operation_details/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ class Base
def self.inherited(base)
base.singleton_class.prepend(
Module.new do
def apply(operation, line)
operation.instance_variable_set(:"@#{line.detail_code}", line.detail)
def apply(details, line)
details.instance_variable_set(:"@#{line.detail_code}", line.detail)

super
end
Expand Down
6 changes: 3 additions & 3 deletions lib/cfonb/operation_details/fee.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ module OperationDetails
class FEE < Base
ATTRIBUTES = %i[fee fee_currency].freeze

def self.apply(operation, line)
operation.fee_currency = line.detail[0..2]
def self.apply(details, line)
details.fee_currency = line.detail[0..2]
scale = line.detail[3].to_i

operation.fee = BigDecimal(line.detail[4..17]) / (10**scale)
details.fee = BigDecimal(line.detail[4..17]) / (10**scale)
end

CFONB::OperationDetails.register('FEE', self)
Expand Down
6 changes: 3 additions & 3 deletions lib/cfonb/operation_details/ibe.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ module OperationDetails
class IBE < Base
ATTRIBUTES = %i[creditor_identifier creditor_identifier_type].freeze

def self.apply(operation, line)
operation.creditor_identifier = line.detail[0..34].strip
operation.creditor_identifier_type = line.detail[35..-1].strip
def self.apply(details, line)
details.creditor_identifier = line.detail[0..34].strip
details.creditor_identifier_type = line.detail[35..-1].strip
end

CFONB::OperationDetails.register('IBE', self)
Expand Down
6 changes: 3 additions & 3 deletions lib/cfonb/operation_details/ipy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ module OperationDetails
class IPY < Base
ATTRIBUTES = %i[debtor_identifier debtor_identifier_type].freeze

def self.apply(operation, line)
operation.debtor_identifier = line.detail[0..34].strip
operation.debtor_identifier_type = line.detail[35..-1].strip
def self.apply(details, line)
details.debtor_identifier = line.detail[0..34].strip
details.debtor_identifier_type = line.detail[35..-1].strip
end

CFONB::OperationDetails.register('IPY', self)
Expand Down
6 changes: 4 additions & 2 deletions lib/cfonb/operation_details/lc2.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@
module CFONB
module OperationDetails
class LC2 < Base
def self.apply(operation, line)
operation.label += "\n#{line.detail.strip}"
ATTRIBUTES = %i[unstructured_label_2].freeze

def self.apply(details, line)
details.unstructured_label_2 = line.detail.strip
end

CFONB::OperationDetails.register('LC2', self)
Expand Down
6 changes: 4 additions & 2 deletions lib/cfonb/operation_details/lcc.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@
module CFONB
module OperationDetails
class LCC < Base
def self.apply(operation, line)
operation.label += "\n#{line.detail.strip}"
ATTRIBUTES = %i[unstructured_label].freeze

def self.apply(details, line)
details.unstructured_label = line.detail.strip.to_s
end

CFONB::OperationDetails.register('LCC', self)
Expand Down
6 changes: 4 additions & 2 deletions lib/cfonb/operation_details/lcs.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@
module CFONB
module OperationDetails
class LCS < Base
def self.apply(operation, line)
operation.label += "\n#{line.detail[0..35].strip}"
ATTRIBUTES = %i[structured_label].freeze

def self.apply(details, line)
details.structured_label = line.detail[0..35].strip
end

CFONB::OperationDetails.register('LCS', self)
Expand Down
6 changes: 4 additions & 2 deletions lib/cfonb/operation_details/lib.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@
module CFONB
module OperationDetails
class LIB < Base
def self.apply(operation, line)
operation.label += "\n#{line.detail.strip}"
ATTRIBUTES = %i[free_label].freeze

def self.apply(details, line)
details.free_label = [details.free_label, line.detail.strip].compact.join("\n")
end

CFONB::OperationDetails.register('LIB', self)
Expand Down
10 changes: 4 additions & 6 deletions lib/cfonb/operation_details/mmo.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,17 @@ module OperationDetails
class MMO < Base
ATTRIBUTES = %i[original_currency original_amount exchange_rate].freeze

def self.apply(operation, line)
operation.original_currency = line.detail[0..2]

def self.apply(details, line)
details.original_currency = line.detail[0..2]
scale = line.detail[3].to_i
sign = operation.amount <=> 0 # the detail amount is unsigned

operation.original_amount = sign * BigDecimal(line.detail[4..17]) / (10**scale)
details.original_amount = BigDecimal(line.detail[4..17]) / (10**scale)
exchange_rate_value = line.detail[26..29]

return if exchange_rate_value.nil? || exchange_rate_value.strip.empty?

exchange_rate_scale = line.detail[18]
operation.exchange_rate = BigDecimal(exchange_rate_value) / (10**BigDecimal(exchange_rate_scale))
details.exchange_rate = BigDecimal(exchange_rate_value) / (10**BigDecimal(exchange_rate_scale))
end

CFONB::OperationDetails.register('MMO', self)
Expand Down
4 changes: 2 additions & 2 deletions lib/cfonb/operation_details/nbe.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ module OperationDetails
class NBE < Base
ATTRIBUTES = %i[creditor].freeze

def self.apply(operation, line)
operation.creditor = line.detail.strip
def self.apply(details, line)
details.creditor = line.detail.strip
end

CFONB::OperationDetails.register('NBE', self)
Expand Down
4 changes: 2 additions & 2 deletions lib/cfonb/operation_details/nbu.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ module OperationDetails
class NBU < Base
ATTRIBUTES = %i[ultimate_creditor].freeze

def self.apply(operation, line)
operation.ultimate_creditor = line.detail.strip
def self.apply(details, line)
details.ultimate_creditor = line.detail.strip
end

CFONB::OperationDetails.register('NBU', self)
Expand Down
4 changes: 2 additions & 2 deletions lib/cfonb/operation_details/npo.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ module OperationDetails
class NPO < Base
ATTRIBUTES = %i[ultimate_debtor].freeze

def self.apply(operation, line)
operation.ultimate_debtor = line.detail.strip
def self.apply(details, line)
details.ultimate_debtor = line.detail.strip
end

CFONB::OperationDetails.register('NPO', self)
Expand Down
4 changes: 2 additions & 2 deletions lib/cfonb/operation_details/npy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ module OperationDetails
class NPY < Base
ATTRIBUTES = %i[debtor].freeze

def self.apply(operation, line)
operation.debtor = line.detail.strip
def self.apply(details, line)
details.debtor = line.detail.strip
end

CFONB::OperationDetails.register('NPY', self)
Expand Down
12 changes: 4 additions & 8 deletions lib/cfonb/operation_details/rcn.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,11 @@ module OperationDetails
class RCN < Base
using CFONB::Refinements::Strings

ATTRIBUTES = %i[reference purpose].freeze
ATTRIBUTES = %i[client_reference purpose].freeze

def self.apply(operation, line)
operation.reference = [
operation.reference,
line.detail[0..34].strip,
].filter_map(&:presence).join(' - ')

operation.purpose = line.detail[35..-1]&.strip
def self.apply(details, line)
details.client_reference = line.detail[0..34].strip
details.purpose = line.detail[35..-1]&.strip
end

CFONB::OperationDetails.register('RCN', self)
Expand Down
9 changes: 3 additions & 6 deletions lib/cfonb/operation_details/ref.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,10 @@ module OperationDetails
class REF < Base
using CFONB::Refinements::Strings

ATTRIBUTES = %i[reference].freeze
ATTRIBUTES = %i[operation_reference].freeze

def self.apply(operation, line)
operation.reference = [
operation.reference,
line.detail.strip,
].filter_map(&:presence).join(' - ')
def self.apply(details, line)
details.operation_reference = line.detail.strip
end

CFONB::OperationDetails.register('REF', self)
Expand Down
Loading

0 comments on commit b6fef0c

Please sign in to comment.