Module: Ibandit::IBANAssembler

Defined in:
lib/ibandit/iban_assembler.rb

Constant Summary collapse

SUPPORTED_COUNTRY_CODES =
%w(AT BE CY DE EE ES FI FR GB GR IE IT LT LU LV MC
MT NL NO PT SE SI SK SM).freeze
EXCEPTION_COUNTRY_CODES =
%w(IT SM BE).freeze

Class Method Summary collapse

Class Method Details

.allowed_fields(country_code) ⇒ Object



96
97
98
99
100
101
102
103
104
105
# File 'lib/ibandit/iban_assembler.rb', line 96

def self.allowed_fields(country_code)
  # Some countries have additional optional fields
  case country_code
  when 'BE' then i(bank_code )
  when 'CY' then i(bank_code branch_code )
  when 'IT' then i(bank_code branch_code  check_digit)
  when 'SK' then i(bank_code  )
  else required_fields(country_code)
  end
end

.assemble(local_details) ⇒ Object



8
9
10
11
12
13
14
15
16
17
18
19
20
21
# File 'lib/ibandit/iban_assembler.rb', line 8

def self.assemble(local_details)
  country_code = local_details[:country_code]

  return unless can_assemble?(local_details)

  bban =
    if EXCEPTION_COUNTRY_CODES.include?(country_code)
      public_send(:"assemble_#{country_code.downcase}_bban", local_details)
    else
      assemble_general_bban(local_details)
    end

  assemble_iban(country_code, bban)
end

.assemble_be_bban(opts) ⇒ Object

Country-specific BBAN creation #



35
36
37
38
39
40
41
42
# File 'lib/ibandit/iban_assembler.rb', line 35

def self.assemble_be_bban(opts)
  # The first three digits of Belgian account numbers are the bank_code,
  # but the account number is not considered complete without these three
  # numbers and the IBAN structure file includes them in its definition of
  # the account number. As a result, this method ignores all arguments
  # other than the account number.
  opts[:account_number]
end

.assemble_general_bban(opts) ⇒ Object

General case BBAN creation #



27
28
29
# File 'lib/ibandit/iban_assembler.rb', line 27

def self.assemble_general_bban(opts)
  [opts[:bank_code], opts[:branch_code], opts[:account_number]].join
end

.assemble_iban(country_code, bban) ⇒ Object



107
108
109
110
111
112
113
114
115
# File 'lib/ibandit/iban_assembler.rb', line 107

def self.assemble_iban(country_code, bban)
  [
    country_code,
    CheckDigit.iban(country_code, bban),
    bban
  ].join
rescue InvalidCharacterError
  nil
end

.assemble_it_bban(opts) ⇒ Object



44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/ibandit/iban_assembler.rb', line 44

def self.assemble_it_bban(opts)
  # The  Italian check digit is NOT included in the any of the other SWIFT
  # elements, so should be passed explicitly or left blank for it to be
  # calculated implicitly
  partial_bban = [
    opts[:bank_code],
    opts[:branch_code],
    opts[:account_number]
  ].join

  check_digit = opts[:check_digit] || CheckDigit.italian(partial_bban)

  [check_digit, partial_bban].join
end

.assemble_sm_bban(opts) ⇒ Object



59
60
61
62
# File 'lib/ibandit/iban_assembler.rb', line 59

def self.assemble_sm_bban(opts)
  # San Marino uses the same BBAN construction method as Italy
  assemble_it_bban(opts)
end

.can_assemble?(local_details) ⇒ Boolean

Helper methods #



68
69
70
71
# File 'lib/ibandit/iban_assembler.rb', line 68

def self.can_assemble?(local_details)
  SUPPORTED_COUNTRY_CODES.include?(local_details[:country_code]) &&
    valid_arguments?(local_details)
end

.required_fields(country_code) ⇒ Object



85
86
87
88
89
90
91
92
93
94
# File 'lib/ibandit/iban_assembler.rb', line 85

def self.required_fields(country_code)
  case country_code
  when *%w(AT CY DE EE FI LT LU LV NL NO SE SI SK)
    i(bank_code )
  when 'BE'
    i()
  else
    i(bank_code branch_code )
  end
end

.valid_arguments?(local_details) ⇒ Boolean



73
74
75
76
77
78
79
80
81
82
83
# File 'lib/ibandit/iban_assembler.rb', line 73

def self.valid_arguments?(local_details)
  country_code = local_details[:country_code]

  supplied = local_details.keys.select { |key| local_details[key] }
  supplied.delete(:country_code)

  allowed = allowed_fields(country_code)

  required_fields(country_code).all? { |key| supplied.include?(key) } &&
    supplied.all? { |key| allowed.include?(key) }
end