Module: Ibandit::LocalDetailsCleaner

Defined in:
lib/ibandit/local_details_cleaner.rb

Class Method Summary collapse

Class Method Details

.can_clean?(country_code, local_details) ⇒ Boolean

Helpers #

Returns:

  • (Boolean)


20
21
22
23
# File 'lib/ibandit/local_details_cleaner.rb', line 20

def self.can_clean?(country_code, local_details)
  Constants::SUPPORTED_COUNTRY_CODES.include?(country_code) &&
    fields_for?(country_code, local_details)
end

.clean(local_details) ⇒ Object



3
4
5
6
7
8
9
10
11
12
13
14
# File 'lib/ibandit/local_details_cleaner.rb', line 3

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

  if can_clean?(country_code, local_details)
    local_details = local_details.merge(
      public_send(:"clean_#{country_code.downcase}_details", local_details))
  end

  return local_details if explicit_swift_details?(country_code)

  swift_details_for(local_details).merge(local_details)
end

.clean_at_details(local_details) ⇒ Object

Country-specific logic #



52
53
54
55
56
57
58
59
60
# File 'lib/ibandit/local_details_cleaner.rb', line 52

def self.clean_at_details(local_details)
  # Account number may be 4-11 digits long.
  # Add leading zeros to account number if < 11 digits.
  return {} unless local_details[:account_number].length >= 4
  {
    bank_code:      local_details[:bank_code],
    account_number: local_details[:account_number].rjust(11, '0')
  }
end

.clean_be_details(local_details) ⇒ Object



62
63
64
65
66
67
68
69
# File 'lib/ibandit/local_details_cleaner.rb', line 62

def self.clean_be_details(local_details)
   = local_details[:account_number].tr('-', '')

  {
    bank_code:      local_details[:bank_code] || .slice(0, 3),
    account_number: 
  }
end

.clean_bg_details(local_details) ⇒ Object



71
72
73
74
# File 'lib/ibandit/local_details_cleaner.rb', line 71

def self.clean_bg_details(local_details)
  # Bulgarian national bank details were replaced with IBANs in 2006.
  local_details
end

.clean_cy_details(local_details) ⇒ Object



76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/ibandit/local_details_cleaner.rb', line 76

def self.clean_cy_details(local_details)
  # Account number may be 7-16 digits long.
  # Add leading zeros to account number if < 16 digits.
  cleaned_bank_code = local_details[:bank_code].gsub(/[-\s]/, '')

  bank_code      = cleaned_bank_code.slice(0, 3)
  branch_code    =
    if local_details[:branch_code]
      local_details[:branch_code]
    elsif cleaned_bank_code.length > 3
      cleaned_bank_code[3..-1]
    end
   =
    if local_details[:account_number].length >= 7
      local_details[:account_number].rjust(16, '0')
    else
      local_details[:account_number]
    end

  {
    bank_code:      bank_code,
    branch_code:    branch_code,
    account_number: 
  }
end

.clean_cz_details(local_details) ⇒ Object



102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/ibandit/local_details_cleaner.rb', line 102

def self.clean_cz_details(local_details)
  #   The SWIFT definition of a Czech IBAN includes both the account
  #   number prefix and the account number. This method therefore supports
  #   passing those fields concatenated.
   =
    if local_details.include?(:account_number_prefix)
      [
        local_details[:account_number_prefix].rjust(6, '0'),
        local_details[:account_number].rjust(10, '0')
      ].join
    else
      local_details[:account_number].tr('-', '').rjust(16, '0')
    end

  {
    bank_code:      local_details[:bank_code],
    account_number: 
  }
end

.clean_de_details(local_details) ⇒ Object



122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
# File 'lib/ibandit/local_details_cleaner.rb', line 122

def self.clean_de_details(local_details)
  # Account number may be up to 10 digits long.
  # Add leading zeros to account number if < 10 digits.
  #
  # There are many exceptions to the way German bank details translate
  # into an IBAN, detailed into a 200 page document compiled by the
  # Bundesbank, and handled by the GermanDetailsConverter class.
  converted_details =
    begin
      GermanDetailsConverter.convert(local_details)
    rescue UnsupportedAccountDetails
      local_details.dup
    end

  return {} unless converted_details[:account_number].length >= 4

  {
    bank_code:      converted_details[:bank_code],
    account_number: converted_details[:account_number].rjust(10, '0')
  }
end

.clean_dk_details(local_details) ⇒ Object



144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
# File 'lib/ibandit/local_details_cleaner.rb', line 144

def self.clean_dk_details(local_details)
  # This method supports being passed the component IBAN parts, as defined
  # by SWIFT, or a single traditional-format string split by a '-'.
  if local_details[:bank_code]
    bank_code      = local_details[:bank_code].rjust(4, '0')
     = local_details[:account_number].rjust(10, '0')
  elsif local_details[:account_number].include?('-')
    bank_code,  = local_details[:account_number].split('-', 2)
  elsif local_details[:account_number].gsub(/\s/, '').length == 14
     = local_details[:account_number].gsub(/\s/, '')
    bank_code      = .slice(0, 4)
     = .slice(4, 10)
  else
    return {}
  end

  {
    bank_code:      bank_code.rjust(4, '0'),
    account_number: .delete('-').rjust(10, '0')
  }
end

.clean_ee_details(local_details) ⇒ Object



166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
# File 'lib/ibandit/local_details_cleaner.rb', line 166

def self.clean_ee_details(local_details)
  # Account number may be up to 14 characters long.
  # Add leading zeros to account number if < 14 digits.
  #
  # Bank code can be found by extracted from the first two digits of the
  # account number and converted using the rules at
  # http://www.pangaliit.ee/en/settlements-and-standards/bank-codes-of-estonian-banks
  domestic_bank_code =
    local_details[:account_number].gsub(/\A0+/, '').slice(0, 2)

  iban_bank_code =
    case domestic_bank_code
    when '11' then '22'
    when '93' then '00'
    else domestic_bank_code
    end

   = local_details[:account_number].rjust(14, '0')

  { bank_code: iban_bank_code, account_number:  }
end

.clean_es_details(local_details) ⇒ Object



188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
# File 'lib/ibandit/local_details_cleaner.rb', line 188

def self.clean_es_details(local_details)
  # This method supports being passed the component IBAN parts, as defined
  # by SWIFT, or a single 20 digit string.
  if local_details[:bank_code] && local_details[:branch_code]
    bank_code      = local_details[:bank_code]
    branch_code    = local_details[:branch_code]
     = local_details[:account_number].gsub(/[-\s]/, '')
  else
     =
      local_details[:account_number].gsub(/[-\s]/, '')

    bank_code      = .slice(0, 4)
    branch_code    = .slice(4, 4)
     = [8..-1]
  end

  {
    bank_code:      bank_code,
    branch_code:    branch_code,
    account_number: 
  }
end

.clean_fi_details(local_details) ⇒ Object



211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
# File 'lib/ibandit/local_details_cleaner.rb', line 211

def self.clean_fi_details(local_details)
  #   Finnish account numbers need to be expanded into "electronic format"
  #   by adding zero-padding. The expansion method depends on the first
  #   character of the bank code.
   =
    if %w(4 5 6).include?(local_details[:bank_code][0])
      [
        local_details[:account_number][0],
        local_details[:account_number][1..-1].rjust(7, '0')
      ].join
    else
      local_details[:account_number].rjust(8, '0')
    end

  {
    bank_code:      local_details[:bank_code],
    account_number: 
  }
end

.clean_fr_details(local_details) ⇒ Object



231
232
233
234
235
236
237
# File 'lib/ibandit/local_details_cleaner.rb', line 231

def self.clean_fr_details(local_details)
  {
    bank_code:      local_details[:bank_code],
    branch_code:    local_details[:branch_code],
    account_number: local_details[:account_number].gsub(/[-\s]/, '')
  }
end

.clean_gb_details(local_details) ⇒ Object



239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
# File 'lib/ibandit/local_details_cleaner.rb', line 239

def self.clean_gb_details(local_details)
  # Account number may be 6-8 digits
  # Add leading zeros to account number if < 8 digits.
  branch_code = local_details[:branch_code].gsub(/[-\s]/, '')

  if local_details[:bank_code]
    bank_code = local_details[:bank_code]
  else
    bic = Ibandit.find_bic('GB', branch_code)
    bank_code = bic.nil? ? nil : bic.slice(0, 4)
  end

   = local_details[:account_number].gsub(/[-\s]/, '')
   = .rjust(8, '0') if .length > 5

  {
    bank_code:      bank_code,
    branch_code:    branch_code,
    account_number: 
  }
end

.clean_gr_details(local_details) ⇒ Object



261
262
263
264
265
# File 'lib/ibandit/local_details_cleaner.rb', line 261

def self.clean_gr_details(local_details)
  # Greek IBANs construction is idiosyncratic to the individual banks, and
  # no central specification is published.
  local_details
end

.clean_hr_details(local_details) ⇒ Object



267
268
269
270
271
272
273
274
275
276
277
278
279
# File 'lib/ibandit/local_details_cleaner.rb', line 267

def self.clean_hr_details(local_details)
  # This method supports being passed the component IBAN parts, as defined
  # by SWIFT, or a single traditional-format string split by a '-'.
  return local_details if local_details[:bank_code]
  return local_details unless local_details[:account_number].include?('-')

  bank_code,  = local_details[:account_number].split('-', 2)

  {
    bank_code:      bank_code,
    account_number: 
  }
end

.clean_hu_details(local_details) ⇒ Object



281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
# File 'lib/ibandit/local_details_cleaner.rb', line 281

def self.clean_hu_details(local_details)
  # This method supports being passed the component IBAN parts, as defined
  # by SWIFT, or a single 16 or 24 digit string.
  if local_details[:bank_code] || local_details[:branch_code]
    return local_details
  end

  cleaned_acct_number = local_details[:account_number].gsub(/[-\s]/, '')

  case cleaned_acct_number.length
  when 16
    {
      bank_code:      cleaned_acct_number.slice(0, 3),
      branch_code:    cleaned_acct_number.slice(3, 4),
      account_number: cleaned_acct_number.slice(7, 9).ljust(17, '0')
    }
  when 24
    {
      bank_code:      cleaned_acct_number.slice(0, 3),
      branch_code:    cleaned_acct_number.slice(3, 4),
      account_number: cleaned_acct_number.slice(7, 17)
    }
  else local_details
  end
end

.clean_ie_details(local_details) ⇒ Object



307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
# File 'lib/ibandit/local_details_cleaner.rb', line 307

def self.clean_ie_details(local_details)
  # Ireland uses the same local details as the United Kingdom
  branch_code = local_details[:branch_code].gsub(/[-\s]/, '')

  if local_details[:bank_code]
    bank_code = local_details[:bank_code]
  else
    bic = Ibandit.find_bic('IE', branch_code)
    bank_code = bic.nil? ? nil : bic.slice(0, 4)
  end

   = local_details[:account_number].gsub(/[-\s]/, '')
   = .rjust(8, '0') if .length > 5

  {
    bank_code:      bank_code,
    branch_code:    branch_code,
    account_number: 
  }
end

.clean_is_details(local_details) ⇒ Object



328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
# File 'lib/ibandit/local_details_cleaner.rb', line 328

def self.clean_is_details(local_details)
  if local_details[:bank_code]
    bank_code = local_details[:bank_code]
    parts = local_details[:account_number].split('-')
  elsif local_details[:account_number].include?('-')
    bank_code, *parts = local_details[:account_number].split('-')
  else
    bank_code = local_details[:account_number].slice(0, 4)
    parts = Array(local_details[:account_number][4..-1])
  end

  {
    bank_code:      bank_code.rjust(4, '0'),
    account_number: (parts)
  }
end

.clean_it_details(local_details) ⇒ Object



345
346
347
348
349
350
351
352
# File 'lib/ibandit/local_details_cleaner.rb', line 345

def self.clean_it_details(local_details)
  # Add leading zeros to account number if < 12 digits.
  {
    bank_code:      local_details[:bank_code],
    branch_code:    local_details[:branch_code],
    account_number: local_details[:account_number].rjust(12, '0')
  }
end

.clean_lt_details(local_details) ⇒ Object



354
355
356
357
# File 'lib/ibandit/local_details_cleaner.rb', line 354

def self.clean_lt_details(local_details)
  # Lithuanian national bank details were replaced with IBANs in 2004.
  local_details
end

.clean_lu_details(local_details) ⇒ Object



359
360
361
362
# File 'lib/ibandit/local_details_cleaner.rb', line 359

def self.clean_lu_details(local_details)
  # Luxembourgian national bank details were replaced with IBANs in 2002.
  local_details
end

.clean_lv_details(local_details) ⇒ Object



364
365
366
367
# File 'lib/ibandit/local_details_cleaner.rb', line 364

def self.clean_lv_details(local_details)
  # Latvian national bank details were replaced with IBANs in 2004.
  local_details
end

.clean_mc_details(local_details) ⇒ Object



369
370
371
372
# File 'lib/ibandit/local_details_cleaner.rb', line 369

def self.clean_mc_details(local_details)
  # Monaco uses the same local details method as France
  clean_fr_details(local_details)
end

.clean_mt_details(local_details) ⇒ Object



374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
# File 'lib/ibandit/local_details_cleaner.rb', line 374

def self.clean_mt_details(local_details)
  # Add leading zeros to account number if < 18 digits.
  branch_code = local_details[:branch_code]

  if local_details[:bank_code]
    bank_code = local_details[:bank_code]
  else
    bic = Ibandit.find_bic('MT', branch_code)
    bank_code = bic.nil? ? nil : bic.slice(0, 4)
  end

   = local_details[:account_number].gsub(/[-\s]/, '')
   = .rjust(18, '0')

  {
    bank_code:      bank_code,
    branch_code:    branch_code,
    account_number: 
  }
end

.clean_nl_details(local_details) ⇒ Object



395
396
397
398
399
400
401
# File 'lib/ibandit/local_details_cleaner.rb', line 395

def self.clean_nl_details(local_details)
  # Add leading zeros to account number if < 10 digits.
  {
    bank_code:      local_details[:bank_code],
    account_number: local_details[:account_number].rjust(10, '0')
  }
end

.clean_no_details(local_details) ⇒ Object



403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
# File 'lib/ibandit/local_details_cleaner.rb', line 403

def self.clean_no_details(local_details)
  # This method supports being passed the component IBAN parts, as defined
  # by SWIFT, or a single 11 digit string.
  if local_details[:bank_code]
    bank_code      = local_details[:bank_code]
     = local_details[:account_number]
  else
    cleaned_acct_number = local_details[:account_number].gsub(/[-.\s]/, '')

    bank_code      = cleaned_acct_number.slice(0, 4)
     = cleaned_acct_number[4..-1]
  end

  {
    bank_code:      bank_code,
    account_number: 
  }
end

.clean_pl_details(local_details) ⇒ Object



422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
# File 'lib/ibandit/local_details_cleaner.rb', line 422

def self.clean_pl_details(local_details)
  # This method supports being passed the component IBAN parts, as defined
  # by SWIFT, or a single 26 digit string.
  if local_details[:bank_code]
    bank_code      = local_details[:bank_code]
     = local_details[:account_number]
  else
    cleaned_acct_number = local_details[:account_number].gsub(/[\s]/, '')

    bank_code      = cleaned_acct_number.slice(2, 8)
     = cleaned_acct_number[10..-1]
  end

  {
    bank_code:      bank_code,
    account_number: 
  }
end

.clean_pt_details(local_details) ⇒ Object



441
442
443
# File 'lib/ibandit/local_details_cleaner.rb', line 441

def self.clean_pt_details(local_details)
  local_details
end

.clean_ro_details(local_details) ⇒ Object



445
446
447
448
# File 'lib/ibandit/local_details_cleaner.rb', line 445

def self.clean_ro_details(local_details)
  # Romanian national bank details were replaced with IBANs in 2004.
  local_details
end

.clean_se_details(local_details) ⇒ Object



450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
# File 'lib/ibandit/local_details_cleaner.rb', line 450

def self.clean_se_details(local_details)
  if local_details[:bank_code]
    # If a bank_code was provided without a branch code we're (probably)
    # dealing with SWIFT details and should just return them.
    return {
      swift_account_number: local_details[:account_number],
      swift_bank_code: local_details[:bank_code]
    }
  else
    Sweden::LocalDetailsConverter.new(
      branch_code: local_details[:branch_code],
      account_number: local_details[:account_number]
    ).convert
  end
end

.clean_si_details(local_details) ⇒ Object



466
467
468
469
470
471
472
# File 'lib/ibandit/local_details_cleaner.rb', line 466

def self.clean_si_details(local_details)
  # Add leading zeros to account number if < 10 digits.
  {
    bank_code:      local_details[:bank_code],
    account_number: local_details[:account_number].rjust(10, '0')
  }
end

.clean_sk_details(local_details) ⇒ Object



474
475
476
477
# File 'lib/ibandit/local_details_cleaner.rb', line 474

def self.clean_sk_details(local_details)
  # Slovakia uses the same local details method as the Czech Republic
  clean_cz_details(local_details)
end

.clean_sm_details(local_details) ⇒ Object



479
480
481
482
# File 'lib/ibandit/local_details_cleaner.rb', line 479

def self.clean_sm_details(local_details)
  # San Marino uses the same local details method as France
  clean_it_details(local_details)
end

.explicit_swift_details?(country_code) ⇒ Boolean

Returns:

  • (Boolean)


25
26
27
# File 'lib/ibandit/local_details_cleaner.rb', line 25

def self.explicit_swift_details?(country_code)
  Constants::PSEUDO_IBAN_COUNTRY_CODES.include?(country_code)
end

.fields_for?(country_code, opts) ⇒ Boolean

Returns:

  • (Boolean)


29
30
31
# File 'lib/ibandit/local_details_cleaner.rb', line 29

def self.fields_for?(country_code, opts)
  required_fields(country_code).all? { |argument| opts[argument] }
end

.required_fields(country_code) ⇒ Object



33
34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/ibandit/local_details_cleaner.rb', line 33

def self.required_fields(country_code)
  case country_code
  when 'AT', 'CY', 'DE', 'FI', 'LT', 'LU', 'LV', 'NL', 'RO', 'SI', 'SK'
    %i(bank_code account_number)
  when 'BE', 'CZ', 'DK', 'EE', 'ES', 'HR', 'HU', 'IS', 'NO', 'PL', 'SE'
    %i(account_number)
  when 'GB', 'IE', 'MT'
    if Ibandit.bic_finder.nil? then %i(bank_code branch_code account_number)
    else %i(branch_code account_number)
    end
  else
    %i(bank_code branch_code account_number)
  end
end