Class: Ibandit::IBAN

Inherits:
Object
  • Object
show all
Defined in:
lib/ibandit/iban.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(argument) ⇒ IBAN

Returns a new instance of IBAN.



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

def initialize(argument)
  if argument.is_a?(String)
    @iban = argument.to_s.gsub(/\s+/, '').upcase
    extract_local_details_from_iban!
  elsif argument.is_a?(Hash)
    build_iban_from_local_details(argument)
  else
    raise TypeError, 'Must pass an IBAN string or hash of local details'
  end

  @errors = {}
end

Instance Attribute Details

#account_numberObject (readonly)

Returns the value of attribute account_number.



5
6
7
# File 'lib/ibandit/iban.rb', line 5

def 
  @account_number
end

#bank_codeObject (readonly)

Returns the value of attribute bank_code.



5
6
7
# File 'lib/ibandit/iban.rb', line 5

def bank_code
  @bank_code
end

#branch_codeObject (readonly)

Returns the value of attribute branch_code.



5
6
7
# File 'lib/ibandit/iban.rb', line 5

def branch_code
  @branch_code
end

#check_digitsObject (readonly)

Returns the value of attribute check_digits.



5
6
7
# File 'lib/ibandit/iban.rb', line 5

def check_digits
  @check_digits
end

#country_codeObject (readonly)

Returns the value of attribute country_code.



5
6
7
# File 'lib/ibandit/iban.rb', line 5

def country_code
  @country_code
end

#errorsObject (readonly)

Returns the value of attribute errors.



5
6
7
# File 'lib/ibandit/iban.rb', line 5

def errors
  @errors
end

#ibanObject (readonly)

Returns the value of attribute iban.



5
6
7
# File 'lib/ibandit/iban.rb', line 5

def iban
  @iban
end

Instance Method Details

#bbanObject



50
51
52
# File 'lib/ibandit/iban.rb', line 50

def bban
  iban[4..-1] unless iban.nil?
end

#iban_national_idObject

Component parts #



33
34
35
36
37
38
39
# File 'lib/ibandit/iban.rb', line 33

def iban_national_id
  return unless decomposable?

  national_id = bank_code.to_s
  national_id += branch_code.to_s
  national_id.slice(0, structure[:iban_national_id_length])
end

#local_check_digitsObject



41
42
43
44
45
46
47
48
# File 'lib/ibandit/iban.rb', line 41

def local_check_digits
  return unless decomposable? && structure[:local_check_digit_position]

  iban.slice(
    structure[:local_check_digit_position] - 1,
    structure[:local_check_digit_length]
  )
end

#passes_country_specific_checks?Boolean

Returns:

  • (Boolean)


228
229
230
231
232
233
234
235
236
# File 'lib/ibandit/iban.rb', line 228

def passes_country_specific_checks?
  return unless valid_country_code?

  case country_code
  when 'DE' then supports_iban_determination?
  when 'SE' then valid_swedish_details?
  else true
  end
end

#supports_iban_determination?Boolean

Returns:

  • (Boolean)


238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
# File 'lib/ibandit/iban.rb', line 238

def supports_iban_determination?
  return unless valid_format?
  return true unless country_code == 'DE'

  begin
    GermanDetailsConverter.convert(
      country_code: country_code,
      bank_code: bank_code,
      account_number: 
    )
    true
  rescue UnsupportedAccountDetails
    @errors[:account_number] = Ibandit.translate(:does_not_support_payments)
    false
  end
end

#to_s(format = :compact) ⇒ Object



21
22
23
24
25
26
27
# File 'lib/ibandit/iban.rb', line 21

def to_s(format = :compact)
  case format
  when :compact   then iban.to_s
  when :formatted then formatted
  else raise ArgumentError, "invalid format '#{format}'"
  end
end

#valid?Boolean

Validations #

Returns:

  • (Boolean)


58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/ibandit/iban.rb', line 58

def valid?
  [
    valid_country_code?,
    valid_characters?,
    valid_check_digits?,
    valid_length?,
    valid_bank_code_length?,
    valid_branch_code_length?,
    ,
    valid_format?,
    valid_bank_code_format?,
    valid_branch_code_format?,
    ,
    valid_local_modulus_check?,
    passes_country_specific_checks?
  ].all?
end

#valid_account_number_format?Boolean

Returns:

  • (Boolean)


210
211
212
213
214
215
216
217
218
219
# File 'lib/ibandit/iban.rb', line 210

def 
  return unless 

  if  =~ Regexp.new(structure[:account_number_format])
    true
  else
    @errors[:account_number] = Ibandit.translate(:is_invalid)
    false
  end
end

#valid_account_number_length?Boolean

Returns:

  • (Boolean)


147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
# File 'lib/ibandit/iban.rb', line 147

def 
  return unless valid_country_code?

  if .nil?
    @errors[:account_number] = Ibandit.translate(:is_required)
    return false
  end

  return true if .length == structure[:account_number_length]

  @errors[:account_number] =
    Ibandit.translate(:wrong_length,
                      expected: structure[:account_number_length])
  false
end

#valid_bank_code_format?Boolean

Returns:

  • (Boolean)


187
188
189
190
191
192
193
194
195
196
# File 'lib/ibandit/iban.rb', line 187

def valid_bank_code_format?
  return unless valid_bank_code_length?

  if bank_code =~ Regexp.new(structure[:bank_code_format])
    true
  else
    @errors[:bank_code] = Ibandit.translate(:is_invalid)
    false
  end
end

#valid_bank_code_length?Boolean

Returns:

  • (Boolean)


115
116
117
118
119
120
121
122
123
124
125
126
127
128
# File 'lib/ibandit/iban.rb', line 115

def valid_bank_code_length?
  return unless valid_country_code?

  if bank_code.nil? || bank_code.length == 0
    @errors[:bank_code] = Ibandit.translate(:is_required)
    return false
  end

  return true if bank_code.length == structure[:bank_code_length]

  @errors[:bank_code] =
    Ibandit.translate(:wrong_length, expected: structure[:bank_code_length])
  false
end

#valid_branch_code_format?Boolean

Returns:

  • (Boolean)


198
199
200
201
202
203
204
205
206
207
208
# File 'lib/ibandit/iban.rb', line 198

def valid_branch_code_format?
  return unless valid_branch_code_length?
  return true unless structure[:branch_code_format]

  if branch_code =~ Regexp.new(structure[:branch_code_format])
    true
  else
    @errors[:branch_code] = Ibandit.translate(:is_invalid)
    false
  end
end

#valid_branch_code_length?Boolean

Returns:

  • (Boolean)


130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# File 'lib/ibandit/iban.rb', line 130

def valid_branch_code_length?
  return unless valid_country_code?
  return true if branch_code.to_s.length == structure[:branch_code_length]

  if structure[:branch_code_length] == 0
    @errors[:branch_code] = Ibandit.translate(:not_used_in_country,
                                              country_code: country_code)
  elsif branch_code.nil? || branch_code.length == 0
    @errors[:branch_code] = Ibandit.translate(:is_required)
  else
    @errors[:branch_code] =
      Ibandit.translate(:wrong_length,
                        expected: structure[:branch_code_length])
  end
  false
end

#valid_characters?Boolean

Returns:

  • (Boolean)


163
164
165
166
167
168
169
170
171
172
173
# File 'lib/ibandit/iban.rb', line 163

def valid_characters?
  return if iban.nil?
  if iban.scan(/[^A-Z0-9]/).any?
    @errors[:characters] =
      Ibandit.translate(:non_alphanumeric_characters,
                        characters: iban.scan(/[^A-Z\d]/).join(' '))
    false
  else
    true
  end
end

#valid_check_digits?Boolean

Returns:

  • (Boolean)


86
87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/ibandit/iban.rb', line 86

def valid_check_digits?
  return unless decomposable? && valid_characters?

  expected_check_digits = CheckDigit.iban(country_code, bban)
  if check_digits == expected_check_digits
    true
  else
    @errors[:check_digits] =
      Ibandit.translate(:invalid_check_digits,
                        expected_check_digits: expected_check_digits,
                        check_digits: check_digits)
    false
  end
end

#valid_country_code?Boolean

Returns:

  • (Boolean)


76
77
78
79
80
81
82
83
84
# File 'lib/ibandit/iban.rb', line 76

def valid_country_code?
  if Ibandit.structures.key?(country_code)
    true
  else
    @errors[:country_code] = Ibandit.translate(:invalid_country_code,
                                               country_code: country_code)
    false
  end
end

#valid_format?Boolean

Returns:

  • (Boolean)


175
176
177
178
179
180
181
182
183
184
185
# File 'lib/ibandit/iban.rb', line 175

def valid_format?
  return unless valid_country_code?

  if bban =~ Regexp.new(structure[:bban_format])
    true
  else
    @errors[:format] = Ibandit.translate(:invalid_format,
                                         country_code: country_code)
    false
  end
end

#valid_length?Boolean

Returns:

  • (Boolean)


101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/ibandit/iban.rb', line 101

def valid_length?
  return unless valid_country_code? && !iban.nil?

  if iban.length == structure[:total_length]
    true
  else
    @errors[:length] =
      Ibandit.translate(:invalid_length,
                        expected_length: structure[:total_length],
                        length: iban.size)
    false
  end
end

#valid_local_modulus_check?Boolean

Returns:

  • (Boolean)


221
222
223
224
225
226
# File 'lib/ibandit/iban.rb', line 221

def valid_local_modulus_check?
  return unless valid_format?
  return true unless Ibandit.modulus_checker

  valid_modulus_check_bank_code? && 
end

#valid_swedish_details?Boolean

Returns:

  • (Boolean)


255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
# File 'lib/ibandit/iban.rb', line 255

def valid_swedish_details?
  return true unless country_code == 'SE'

  bank_details = { bank_code: bank_code, account_number:  }

  unless SwedishDetailsConverter.valid_bank_code?(bank_details)
    bank_code_field = bank_code.nil? ? :account_number : :bank_code
    @errors[bank_code_field] = Ibandit.translate(:is_invalid)
    @errors.delete(:bank_code) if bank_code.nil?
    return false
  end

  unless SwedishDetailsConverter.valid_length?(bank_details)
    @errors[:account_number] = Ibandit.translate(:is_invalid)
    return false
  end

  true
end