ibandit 0.1.1 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +1 -1
- data/CHANGELOG.md +5 -0
- data/README.md +3 -2
- data/bin/build_german_iban_rules.rb +42 -0
- data/bin/build_structure_file.rb +9 -11
- data/data/german_iban_rules.yml +11350 -0
- data/data/raw/BLZ2.txt +18677 -0
- data/data/{IBANSTRUCTURE.xml → raw/IBANSTRUCTURE.xml} +0 -0
- data/data/{IBAN_Registry.txt → raw/IBAN_Registry.txt} +0 -0
- data/data/{structure_additions.yml → raw/structure_additions.yml} +0 -0
- data/{lib/ibandit → data}/structures.yml +0 -0
- data/lib/ibandit.rb +1 -0
- data/lib/ibandit/errors.rb +1 -0
- data/lib/ibandit/german_details_converter.rb +1277 -0
- data/lib/ibandit/iban.rb +4 -1
- data/lib/ibandit/iban_builder.rb +5 -3
- data/lib/ibandit/version.rb +1 -1
- data/spec/fixtures/germany_integration_test_cases.json +170 -0
- data/spec/fixtures/germany_unit_test_cases.json +425 -0
- data/spec/ibandit/german_details_converter_spec.rb +101 -0
- data/spec/ibandit/iban_builder_spec.rb +7 -0
- data/spec/spec_helper.rb +5 -0
- metadata +13 -6
File without changes
|
File without changes
|
File without changes
|
File without changes
|
data/lib/ibandit.rb
CHANGED
data/lib/ibandit/errors.rb
CHANGED
@@ -0,0 +1,1277 @@
|
|
1
|
+
# German bank details don't map directly to IBANs in the same way as in other
|
2
|
+
# countries - each bank has idiosyncracies for translating its cusomers' bank
|
3
|
+
# details. These idiosyncracies are described in a document from the Bundesbank:
|
4
|
+
# http://www.bundesbank.de/Navigation/DE/Aufgaben/Unbarer_Zahlungsverkehr/IBAN_Regeln/iban_regeln.html
|
5
|
+
|
6
|
+
module Ibandit
|
7
|
+
module GermanDetailsConverter
|
8
|
+
def self.rules
|
9
|
+
@rules ||= YAML.load_file(
|
10
|
+
File.expand_path('../../../data/german_iban_rules.yml', __FILE__)
|
11
|
+
)
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.convert(opts)
|
15
|
+
# Fetch the relevant rule number. Default to '000000'
|
16
|
+
rule_num = rules.fetch(opts[:bank_code], {}).fetch(:iban_rule, '000000')
|
17
|
+
|
18
|
+
# Convert the bank details using the relevant rule
|
19
|
+
updated_bank_details = const_get("Rule#{rule_num}").new(
|
20
|
+
opts[:bank_code],
|
21
|
+
opts[:account_number]
|
22
|
+
).converted_details
|
23
|
+
|
24
|
+
opts.merge(updated_bank_details)
|
25
|
+
end
|
26
|
+
|
27
|
+
##############
|
28
|
+
# IBAN Rules #
|
29
|
+
##############
|
30
|
+
|
31
|
+
class BaseRule
|
32
|
+
def initialize(bank_code, account_number)
|
33
|
+
@bank_code = bank_code
|
34
|
+
@account_number = account_number
|
35
|
+
end
|
36
|
+
|
37
|
+
def converted_details
|
38
|
+
raise NotImplementedError, 'Concrete RuleXXXXXX classes should ' \
|
39
|
+
'define a converted_details function'
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
module PseudoAccountNumberBehaviour
|
44
|
+
def self.included(o)
|
45
|
+
o.extend(ClassMethods)
|
46
|
+
end
|
47
|
+
|
48
|
+
module ClassMethods
|
49
|
+
attr_reader :pseudo_account_number_mapping
|
50
|
+
end
|
51
|
+
|
52
|
+
def converted_details
|
53
|
+
updated_account_number =
|
54
|
+
pseudo_account_number_mapping.fetch(
|
55
|
+
@account_number.rjust(10, '0'),
|
56
|
+
@account_number
|
57
|
+
)
|
58
|
+
|
59
|
+
{ bank_code: @bank_code, account_number: updated_account_number }
|
60
|
+
end
|
61
|
+
|
62
|
+
def pseudo_account_number_mapping
|
63
|
+
self.class.pseudo_account_number_mapping.freeze
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
class Rule000000 < BaseRule
|
68
|
+
def converted_details
|
69
|
+
{ bank_code: @bank_code, account_number: @account_number }
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
class Rule000100 < BaseRule
|
74
|
+
def converted_details
|
75
|
+
msg = "Bank code #{@bank_code} is not used for payment transactions"
|
76
|
+
raise UnsupportedAccountDetails, msg
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
class Rule000200 < BaseRule
|
81
|
+
def converted_details
|
82
|
+
if @account_number.rjust(10, '0')[7] == '6' ||
|
83
|
+
@account_number.rjust(10, '0').slice(7, 2) == '86'
|
84
|
+
msg = 'Account does not support payment transactions'
|
85
|
+
raise UnsupportedAccountDetails, msg
|
86
|
+
else
|
87
|
+
{ bank_code: @bank_code, account_number: @account_number }
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
class Rule000300 < BaseRule
|
93
|
+
def converted_details
|
94
|
+
if @account_number == '6161604670'
|
95
|
+
msg = 'Account does not support payment transactions'
|
96
|
+
raise UnsupportedAccountDetails, msg
|
97
|
+
else
|
98
|
+
{ bank_code: @bank_code, account_number: @account_number }
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
class Rule000400 < BaseRule
|
104
|
+
include PseudoAccountNumberBehaviour
|
105
|
+
|
106
|
+
@pseudo_account_number_mapping = {
|
107
|
+
'0000000135' => '0990021440',
|
108
|
+
'0000001111' => '6600012020',
|
109
|
+
'0000001900' => '0920019005',
|
110
|
+
'0000007878' => '0780008006',
|
111
|
+
'0000008888' => '0250030942',
|
112
|
+
'0000009595' => '1653524703',
|
113
|
+
'0000097097' => '0013044150',
|
114
|
+
'0000112233' => '0630025819',
|
115
|
+
'0000336666' => '6604058903',
|
116
|
+
'0000484848' => '0920018963'
|
117
|
+
}
|
118
|
+
end
|
119
|
+
|
120
|
+
class Rule000503 < BaseRule
|
121
|
+
EXCEPTION_BANK_CODES = %w(
|
122
|
+
10080900 25780022 42080082 54280023 65180005 79580099 12080000 25980027
|
123
|
+
42680081 54580020 65380003 80080000 13080000 26080024 43080083 54680022
|
124
|
+
66280053 81080000 14080000 26281420 44080055 55080065 66680013 82080000
|
125
|
+
15080000 26580070 44080057 57080070 67280051 83080000 16080000 26880063
|
126
|
+
44580070 58580074 69280035 84080000 17080000 26981062 45080060 59080090
|
127
|
+
70080056 85080200 18080000 28280012 46080010 60080055 70080057 86080055
|
128
|
+
20080055 29280011 47880031 60080057 70380006 86080057 20080057 30080055
|
129
|
+
49080025 60380002 71180005 87080000 21080050 30080057 50080055 60480008
|
130
|
+
72180002 21280002 31080015 50080057 61080006 73180011 21480003 32080010
|
131
|
+
50080082 61281007 73380004 21580000 33080030 50680002 61480001 73480013
|
132
|
+
22180000 34080031 50780006 62080012 74180009 22181400 34280032 50880050
|
133
|
+
62280012 74380007 22280000 36280071 51380040 63080015 75080003 24080000
|
134
|
+
36580072 52080080 64080014 76080053 24180001 40080040 53080030 64380011
|
135
|
+
79080052 25480021 41280043 54080021 65080009 79380051
|
136
|
+
).freeze
|
137
|
+
|
138
|
+
PSEUDO_ACCOUNT_NUMBER_MAPPING = {
|
139
|
+
'30040000_0000000036' => '0261103600',
|
140
|
+
'47880031_0000000050' => '0519899900',
|
141
|
+
'47840065_0000000050' => '0150103000',
|
142
|
+
'47840065_0000000055' => '0150103000',
|
143
|
+
'70080000_0000000094' => '0928553201',
|
144
|
+
'70040041_0000000094' => '0212808000',
|
145
|
+
'47840065_0000000099' => '0150103000',
|
146
|
+
'37080040_0000000100' => '0269100000',
|
147
|
+
'38040007_0000000100' => '0119160000',
|
148
|
+
'37080040_0000000111' => '0215022000',
|
149
|
+
'51080060_0000000123' => '0012299300',
|
150
|
+
'36040039_0000000150' => '0161620000',
|
151
|
+
'68080030_0000000202' => '0416520200',
|
152
|
+
'30040000_0000000222' => '0348010002',
|
153
|
+
'38040007_0000000240' => '0109024000',
|
154
|
+
'69240075_0000000444' => '0445520000',
|
155
|
+
'60080000_0000000502' => '0901581400',
|
156
|
+
'60040071_0000000502' => '0525950200',
|
157
|
+
'55040022_0000000555' => '0211050000',
|
158
|
+
'39080005_0000000556' => '0204655600',
|
159
|
+
'39040013_0000000556' => '0106555600',
|
160
|
+
'57080070_0000000661' => '0604101200',
|
161
|
+
'26580070_0000000700' => '0710000000',
|
162
|
+
'50640015_0000000777' => '0222222200',
|
163
|
+
'30040000_0000000999' => '0123799900',
|
164
|
+
'86080000_0000001212' => '0480375900',
|
165
|
+
'37040044_0000001888' => '0212129101',
|
166
|
+
'25040066_0000001919' => '0141919100',
|
167
|
+
'10080000_0000001987' => '0928127700',
|
168
|
+
'50040000_0000002000' => '0728400300',
|
169
|
+
'20080000_0000002222' => '0903927200',
|
170
|
+
'38040007_0000003366' => '0385333000',
|
171
|
+
'37080040_0000004004' => '0233533500',
|
172
|
+
'37080040_0000004444' => '0233000300',
|
173
|
+
'43080083_0000004630' => '0825110100',
|
174
|
+
'50080000_0000006060' => '0096736100',
|
175
|
+
'10040000_0000007878' => '0267878700',
|
176
|
+
'10080000_0000008888' => '0928126501',
|
177
|
+
'50080000_0000009000' => '0026492100',
|
178
|
+
'79080052_0000009696' => '0300021700',
|
179
|
+
'79040047_0000009696' => '0680210200',
|
180
|
+
'39080005_0000009800' => '0208457000',
|
181
|
+
'50080000_0000042195' => '0900333200',
|
182
|
+
'32040024_0000047800' => '0155515000',
|
183
|
+
'37080040_0000055555' => '0263602501',
|
184
|
+
'38040007_0000055555' => '0305555500',
|
185
|
+
'50080000_0000101010' => '0090003500',
|
186
|
+
'50040000_0000101010' => '0311011100',
|
187
|
+
'37040044_0000102030' => '0222344400',
|
188
|
+
'86080000_0000121200' => '0480375900',
|
189
|
+
'66280053_0000121212' => '0625242400',
|
190
|
+
'16080000_0000123456' => '0012345600',
|
191
|
+
'29080010_0000124124' => '0107502000',
|
192
|
+
'37080040_0000182002' => '0216603302',
|
193
|
+
'12080000_0000212121' => '4050462200',
|
194
|
+
'37080040_0000300000' => '0983307900',
|
195
|
+
'37040044_0000300000' => '0300000700',
|
196
|
+
'37080040_0000333333' => '0270330000',
|
197
|
+
'38040007_0000336666' => '0105232300',
|
198
|
+
'55040022_0000343434' => '0217900000',
|
199
|
+
'85080000_0000400000' => '0459488501',
|
200
|
+
'37080040_0000414141' => '0041414100',
|
201
|
+
'38040007_0000414141' => '0108000100',
|
202
|
+
'20080000_0000505050' => '0500100600',
|
203
|
+
'37080040_0000555666' => '0055566600',
|
204
|
+
'20080000_0000666666' => '0900732500',
|
205
|
+
'30080000_0000700000' => '0800005000',
|
206
|
+
'70080000_0000700000' => '0750055500',
|
207
|
+
'70080000_0000900000' => '0319966601',
|
208
|
+
'37080040_0000909090' => '0269100000',
|
209
|
+
'38040007_0000909090' => '0119160000',
|
210
|
+
'70080000_0000949494' => '0575757500',
|
211
|
+
'70080000_0001111111' => '0448060000',
|
212
|
+
'70040041_0001111111' => '0152140000',
|
213
|
+
'10080000_0001234567' => '0920192001',
|
214
|
+
'38040007_0001555555' => '0258266600',
|
215
|
+
'76040061_0002500000' => '0482146800',
|
216
|
+
'16080000_0003030400' => '4205227110',
|
217
|
+
'37080040_0005555500' => '0263602501',
|
218
|
+
'75040062_0006008833' => '0600883300',
|
219
|
+
'12080000_0007654321' => '0144000700',
|
220
|
+
'70080000_0007777777' => '0443540000',
|
221
|
+
'70040041_0007777777' => '0213600000',
|
222
|
+
'64140036_0008907339' => '0890733900',
|
223
|
+
'70080000_0009000000' => '0319966601',
|
224
|
+
'61080006_0009999999' => '0202427500',
|
225
|
+
'12080000_0012121212' => '4101725100',
|
226
|
+
'29080010_0012412400' => '0107502000',
|
227
|
+
'34280032_0014111935' => '0645753800',
|
228
|
+
'38040007_0043434343' => '0118163500',
|
229
|
+
'30080000_0070000000' => '0800005000',
|
230
|
+
'70080000_0070000000' => '0750055500',
|
231
|
+
'44040037_0111111111' => '0320565500',
|
232
|
+
'70040041_0400500500' => '0400500500',
|
233
|
+
'60080000_0500500500' => '0901581400',
|
234
|
+
'60040071_0500500500' => '0512700600'
|
235
|
+
}.freeze
|
236
|
+
|
237
|
+
def converted_details
|
238
|
+
updated_account_number =
|
239
|
+
if PSEUDO_ACCOUNT_NUMBER_MAPPING.key?(combined_bank_details)
|
240
|
+
converted_pseudo_account_number
|
241
|
+
else
|
242
|
+
padded_account_number_for_validity
|
243
|
+
end
|
244
|
+
|
245
|
+
if EXCEPTION_BANK_CODES.include?(@bank_code) &&
|
246
|
+
updated_account_number.to_i.between?(998000000, 999499999)
|
247
|
+
msg = 'Account does not support payment transactions'
|
248
|
+
raise UnsupportedAccountDetails, msg
|
249
|
+
end
|
250
|
+
|
251
|
+
{ bank_code: @bank_code, account_number: updated_account_number }
|
252
|
+
end
|
253
|
+
|
254
|
+
private
|
255
|
+
|
256
|
+
def combined_bank_details
|
257
|
+
"#{@bank_code}_#{@account_number.rjust(10, '0')}"
|
258
|
+
end
|
259
|
+
|
260
|
+
def converted_pseudo_account_number
|
261
|
+
PSEUDO_ACCOUNT_NUMBER_MAPPING[combined_bank_details]
|
262
|
+
end
|
263
|
+
|
264
|
+
def padded_account_number_for_validity
|
265
|
+
unpadded_account_number = @account_number.gsub(/\A0+/, '')
|
266
|
+
|
267
|
+
case GermanDetailsConverter.rules[@bank_code][:check_digit_rule]
|
268
|
+
when '13'
|
269
|
+
if unpadded_account_number.size.between?(6, 7)
|
270
|
+
unpadded_account_number + '00'
|
271
|
+
else @account_number
|
272
|
+
end
|
273
|
+
when '76'
|
274
|
+
case unpadded_account_number.size
|
275
|
+
when 7..8
|
276
|
+
if Check76.new(@account_number).valid? then @account_number
|
277
|
+
else unpadded_account_number + '00'
|
278
|
+
end
|
279
|
+
when 5..6 then unpadded_account_number + '00'
|
280
|
+
else @account_number
|
281
|
+
end
|
282
|
+
else @account_number
|
283
|
+
end
|
284
|
+
end
|
285
|
+
|
286
|
+
class Check76
|
287
|
+
def initialize(account_number)
|
288
|
+
@account_number = account_number.rjust(10, '0')
|
289
|
+
end
|
290
|
+
|
291
|
+
def valid?
|
292
|
+
return false unless valid_length? && valid_account_type?
|
293
|
+
[master_number[-1].to_i, 10].include?(remainder)
|
294
|
+
end
|
295
|
+
|
296
|
+
private
|
297
|
+
|
298
|
+
def master_number
|
299
|
+
@account_number.slice(1, 7).gsub(/\A0+/, '')
|
300
|
+
end
|
301
|
+
|
302
|
+
def remainder
|
303
|
+
sum_of_weighted_values % 11
|
304
|
+
end
|
305
|
+
|
306
|
+
def sum_of_weighted_values
|
307
|
+
weighted_values.reduce(0, &:+)
|
308
|
+
end
|
309
|
+
|
310
|
+
def weighted_values
|
311
|
+
weights = [2, 3, 4, 5, 6, 7, 8]
|
312
|
+
|
313
|
+
master_number[0..-2].reverse.chars.map.with_index do |digit, i|
|
314
|
+
digit.to_i * weights[i]
|
315
|
+
end
|
316
|
+
end
|
317
|
+
|
318
|
+
def valid_account_type?
|
319
|
+
[0, 4, 6, 7, 8, 9].include? @account_number[0].to_i
|
320
|
+
end
|
321
|
+
|
322
|
+
def valid_length?
|
323
|
+
[5, 6, 7].include? master_number.size
|
324
|
+
end
|
325
|
+
end
|
326
|
+
end
|
327
|
+
|
328
|
+
class Rule000600 < BaseRule
|
329
|
+
include PseudoAccountNumberBehaviour
|
330
|
+
|
331
|
+
@pseudo_account_number_mapping = {
|
332
|
+
'0001111111' => '0020228888',
|
333
|
+
'0007777777' => '0903286003',
|
334
|
+
'0034343434' => '1000506517',
|
335
|
+
'0000070000' => '0018180018'
|
336
|
+
}
|
337
|
+
end
|
338
|
+
|
339
|
+
class Rule000700 < BaseRule
|
340
|
+
include PseudoAccountNumberBehaviour
|
341
|
+
|
342
|
+
@pseudo_account_number_mapping = {
|
343
|
+
'0000000111' => '0000001115',
|
344
|
+
'0000000221' => '0023002157',
|
345
|
+
'0000001888' => '0018882068',
|
346
|
+
'0000002006' => '1900668508',
|
347
|
+
'0000002626' => '1900730100',
|
348
|
+
'0000003004' => '1900637016',
|
349
|
+
'0000003636' => '0023002447',
|
350
|
+
'0000004000' => '0000004028',
|
351
|
+
'0000004444' => '0000017368',
|
352
|
+
'0000005050' => '0000073999',
|
353
|
+
'0000008888' => '1901335750',
|
354
|
+
'0000030000' => '0009992959',
|
355
|
+
'0000043430' => '1901693331',
|
356
|
+
'0000046664' => '1900399856',
|
357
|
+
'0000055555' => '0034407379',
|
358
|
+
'0000102030' => '1900480466',
|
359
|
+
'0000151515' => '0057762957',
|
360
|
+
'0000222222' => '0002222222',
|
361
|
+
'0000300000' => '0009992959',
|
362
|
+
'0000333333' => '0000033217',
|
363
|
+
'0000414141' => '0000092817',
|
364
|
+
'0000606060' => '0000091025',
|
365
|
+
'0000909090' => '0000090944',
|
366
|
+
'0002602024' => '0005602024',
|
367
|
+
'0003000000' => '0009992959',
|
368
|
+
'0007777777' => '0002222222',
|
369
|
+
'0008090100' => '0000038901',
|
370
|
+
'0014141414' => '0043597665',
|
371
|
+
'0015000023' => '0015002223',
|
372
|
+
'0015151515' => '0057762957',
|
373
|
+
'0022222222' => '0002222222',
|
374
|
+
'0200820082' => '1901783868',
|
375
|
+
'0222220022' => '0002222222'
|
376
|
+
}
|
377
|
+
end
|
378
|
+
|
379
|
+
class Rule000800 < BaseRule
|
380
|
+
def converted_details
|
381
|
+
{ bank_code: '50020200', account_number: @account_number }
|
382
|
+
end
|
383
|
+
end
|
384
|
+
|
385
|
+
class Rule000900 < BaseRule
|
386
|
+
def converted_details
|
387
|
+
updated_account_number =
|
388
|
+
if @account_number.rjust(10, '0').slice(0, 4) == '1116'
|
389
|
+
"3047#{@account_number.rjust(10, '0').slice(4, 6)}"
|
390
|
+
else
|
391
|
+
@account_number
|
392
|
+
end
|
393
|
+
|
394
|
+
{ bank_code: '68351557', account_number: updated_account_number }
|
395
|
+
end
|
396
|
+
end
|
397
|
+
|
398
|
+
class Rule001001 < BaseRule
|
399
|
+
PSEUDO_ACCOUNT_NUMBER_MAPPING = {
|
400
|
+
'50050201_0000002000' => '0000222000',
|
401
|
+
'50050201_0000800000' => '0000180802'
|
402
|
+
}.freeze
|
403
|
+
|
404
|
+
BANK_CODE_MAPPING = {
|
405
|
+
'50050222' => '50050201'
|
406
|
+
}.freeze
|
407
|
+
|
408
|
+
def converted_details
|
409
|
+
updated_account_number = PSEUDO_ACCOUNT_NUMBER_MAPPING.fetch(
|
410
|
+
"#{@bank_code}_#{@account_number.rjust(10, '0')}",
|
411
|
+
@account_number
|
412
|
+
)
|
413
|
+
updated_bank_code = BANK_CODE_MAPPING.fetch(@bank_code, @bank_code)
|
414
|
+
|
415
|
+
{ bank_code: updated_bank_code, account_number: updated_account_number }
|
416
|
+
end
|
417
|
+
end
|
418
|
+
|
419
|
+
class Rule001100 < BaseRule
|
420
|
+
include PseudoAccountNumberBehaviour
|
421
|
+
|
422
|
+
@pseudo_account_number_mapping = {
|
423
|
+
'0000001000' => '0008010001',
|
424
|
+
'0000047800' => '0000047803'
|
425
|
+
}
|
426
|
+
end
|
427
|
+
|
428
|
+
class Rule001201 < BaseRule
|
429
|
+
def converted_details
|
430
|
+
{ bank_code: '50050000', account_number: @account_number }
|
431
|
+
end
|
432
|
+
end
|
433
|
+
|
434
|
+
class Rule001301 < BaseRule
|
435
|
+
def converted_details
|
436
|
+
{ bank_code: '30050000', account_number: @account_number }
|
437
|
+
end
|
438
|
+
end
|
439
|
+
|
440
|
+
class Rule001400 < BaseRule
|
441
|
+
def converted_details
|
442
|
+
{ bank_code: '30060601', account_number: @account_number }
|
443
|
+
end
|
444
|
+
end
|
445
|
+
|
446
|
+
class Rule001501 < BaseRule
|
447
|
+
include PseudoAccountNumberBehaviour
|
448
|
+
|
449
|
+
@pseudo_account_number_mapping = {
|
450
|
+
'0000000094' => '3008888018',
|
451
|
+
'0000000556' => '0000101010',
|
452
|
+
'0000000888' => '0031870011',
|
453
|
+
'0000004040' => '4003600101',
|
454
|
+
'0000005826' => '1015826017',
|
455
|
+
'0000025000' => '0025000110',
|
456
|
+
'0000393393' => '0033013019',
|
457
|
+
'0000444555' => '0032230016',
|
458
|
+
'0000603060' => '6002919018',
|
459
|
+
'0002120041' => '0002130041',
|
460
|
+
'0080868086' => '4007375013',
|
461
|
+
'0400569017' => '4000569017'
|
462
|
+
}
|
463
|
+
end
|
464
|
+
|
465
|
+
class Rule001600 < BaseRule
|
466
|
+
include PseudoAccountNumberBehaviour
|
467
|
+
|
468
|
+
@pseudo_account_number_mapping = { '0000300000' => '0018128012' }
|
469
|
+
end
|
470
|
+
|
471
|
+
class Rule001700 < BaseRule
|
472
|
+
include PseudoAccountNumberBehaviour
|
473
|
+
|
474
|
+
@pseudo_account_number_mapping = {
|
475
|
+
'0000000100' => '2009090013',
|
476
|
+
'0000000111' => '2111111017',
|
477
|
+
'0000000240' => '2100240010',
|
478
|
+
'0000004004' => '2204004016',
|
479
|
+
'0000004444' => '2044444014',
|
480
|
+
'0000006060' => '2016060014',
|
481
|
+
'0000102030' => '1102030016',
|
482
|
+
'0000333333' => '2033333016',
|
483
|
+
'0000909090' => '2009090013',
|
484
|
+
'0050005000' => '5000500013'
|
485
|
+
}
|
486
|
+
end
|
487
|
+
|
488
|
+
class Rule001800 < BaseRule
|
489
|
+
include PseudoAccountNumberBehaviour
|
490
|
+
|
491
|
+
@pseudo_account_number_mapping = {
|
492
|
+
'0000000556' => '0120440110',
|
493
|
+
'5435435430' => '0543543543',
|
494
|
+
'0000002157' => '0121787016',
|
495
|
+
'0000009800' => '0120800019',
|
496
|
+
'0000202050' => '1221864014'
|
497
|
+
}
|
498
|
+
end
|
499
|
+
|
500
|
+
class Rule001900 < BaseRule
|
501
|
+
def converted_details
|
502
|
+
{ bank_code: '50120383', account_number: @account_number }
|
503
|
+
end
|
504
|
+
end
|
505
|
+
|
506
|
+
class Rule002002 < BaseRule
|
507
|
+
def converted_details
|
508
|
+
unpadded_account_number = @account_number.gsub(/\A0+/, '')
|
509
|
+
|
510
|
+
if unpadded_account_number == '9999' && @bank_code == '50070010'
|
511
|
+
return { bank_code: '50070010', account_number: '92777202' }
|
512
|
+
end
|
513
|
+
|
514
|
+
updated_account_number =
|
515
|
+
case unpadded_account_number.size
|
516
|
+
when 5, 6 then unpadded_account_number + '00'
|
517
|
+
when 7 then
|
518
|
+
if Check63.new(unpadded_account_number + '00').valid?
|
519
|
+
unpadded_account_number + '00'
|
520
|
+
else
|
521
|
+
unpadded_account_number
|
522
|
+
end
|
523
|
+
when 8, 9 then unpadded_account_number
|
524
|
+
else
|
525
|
+
msg = 'Account does not support payment transactions'
|
526
|
+
raise UnsupportedAccountDetails, msg
|
527
|
+
end
|
528
|
+
|
529
|
+
{ bank_code: @bank_code, account_number: updated_account_number }
|
530
|
+
end
|
531
|
+
|
532
|
+
class Check63
|
533
|
+
# A Deutsche Bank specific variant of Check 63
|
534
|
+
def initialize(account_number)
|
535
|
+
@account_number = account_number.dup.rjust(10, '0')
|
536
|
+
end
|
537
|
+
|
538
|
+
def valid?
|
539
|
+
expected_check_digit = (10 - remainder) % 10
|
540
|
+
expected_check_digit == @account_number[-3].to_i
|
541
|
+
end
|
542
|
+
|
543
|
+
private
|
544
|
+
|
545
|
+
def remainder
|
546
|
+
sum_of_weighted_digits % 10
|
547
|
+
end
|
548
|
+
|
549
|
+
def sum_of_weighted_digits
|
550
|
+
weighted_digits.reduce(0, &:+)
|
551
|
+
end
|
552
|
+
|
553
|
+
def weighted_digits
|
554
|
+
weighted_values.flat_map { |value| value.to_s.chars.map(&:to_i) }
|
555
|
+
end
|
556
|
+
|
557
|
+
def weighted_values
|
558
|
+
weights = [2, 1, 2, 1, 2, 1]
|
559
|
+
|
560
|
+
@account_number.slice(1, 6).reverse.chars.map.with_index do |digit, i|
|
561
|
+
digit.to_i * weights[i]
|
562
|
+
end
|
563
|
+
end
|
564
|
+
end
|
565
|
+
end
|
566
|
+
|
567
|
+
class Rule002101 < BaseRule
|
568
|
+
def converted_details
|
569
|
+
{ bank_code: '36020030', account_number: @account_number }
|
570
|
+
end
|
571
|
+
end
|
572
|
+
|
573
|
+
class Rule002200 < BaseRule
|
574
|
+
include PseudoAccountNumberBehaviour
|
575
|
+
|
576
|
+
@pseudo_account_number_mapping = { '0001111111' => '2222200000' }
|
577
|
+
end
|
578
|
+
|
579
|
+
class Rule002300 < BaseRule
|
580
|
+
include PseudoAccountNumberBehaviour
|
581
|
+
|
582
|
+
@pseudo_account_number_mapping = { '0000000700' => '1000700800' }
|
583
|
+
end
|
584
|
+
|
585
|
+
class Rule002400 < BaseRule
|
586
|
+
include PseudoAccountNumberBehaviour
|
587
|
+
|
588
|
+
@pseudo_account_number_mapping = {
|
589
|
+
'0000000094' => '0000001694',
|
590
|
+
'0000000248' => '0000017248',
|
591
|
+
'0000000345' => '0000017345',
|
592
|
+
'0000000400' => '0000014400'
|
593
|
+
}
|
594
|
+
end
|
595
|
+
|
596
|
+
class Rule002500 < BaseRule
|
597
|
+
def converted_details
|
598
|
+
{ bank_code: '60050101', account_number: @account_number }
|
599
|
+
end
|
600
|
+
end
|
601
|
+
|
602
|
+
class Rule002600 < Rule000000
|
603
|
+
# Rule 0026 is actually about modulus checking, not IBAN construction
|
604
|
+
end
|
605
|
+
|
606
|
+
class Rule002700 < Rule000000
|
607
|
+
# Rule 0027 is actually about modulus checking, not IBAN construction
|
608
|
+
end
|
609
|
+
|
610
|
+
class Rule002800 < BaseRule
|
611
|
+
def converted_details
|
612
|
+
{ bank_code: '25050180', account_number: @account_number }
|
613
|
+
end
|
614
|
+
end
|
615
|
+
|
616
|
+
class Rule002900 < BaseRule
|
617
|
+
def converted_details
|
618
|
+
updated_account_number =
|
619
|
+
if @account_number.size == 10 && @account_number[3] == '0'
|
620
|
+
"0#{@account_number.slice(0, 3)}#{@account_number.slice(4, 6)}"
|
621
|
+
else
|
622
|
+
@account_number
|
623
|
+
end
|
624
|
+
|
625
|
+
{ bank_code: @bank_code, account_number: updated_account_number }
|
626
|
+
end
|
627
|
+
end
|
628
|
+
|
629
|
+
class Rule003000 < Rule000000
|
630
|
+
# Rule 0030 is actually about modulus checking, not IBAN construction
|
631
|
+
end
|
632
|
+
|
633
|
+
class Rule003101 < BaseRule
|
634
|
+
# This rule appears to be obsolete - no entries in the BLZ use it. The
|
635
|
+
# table below, which maps old Hypo bank codes to new ones, is used by
|
636
|
+
# other checks though.
|
637
|
+
#
|
638
|
+
BANK_CODE_MAPPING = {
|
639
|
+
'100' => '76020070', '101' => '10020890', '102' => '78320076',
|
640
|
+
'103' => '79320075', '104' => '76320072', '105' => '79020076',
|
641
|
+
'106' => '79320075', '107' => '79320075', '108' => '77320072',
|
642
|
+
'109' => '79320075', '110' => '76220073', '111' => '76020070',
|
643
|
+
'112' => '79320075', '113' => '76020070', '114' => '76020070',
|
644
|
+
'115' => '76520071', '117' => '77120073', '118' => '76020070',
|
645
|
+
'119' => '75320075', '120' => '72120078', '121' => '76220073',
|
646
|
+
'122' => '76320072', '123' => '76420080', '124' => '76320072',
|
647
|
+
'125' => '79520070', '126' => '77320072', '127' => '78020070',
|
648
|
+
'128' => '78020070', '129' => '77120073', '130' => '78020070',
|
649
|
+
'131' => '78020070', '132' => '60020290', '134' => '78020070',
|
650
|
+
'135' => '77020070', '136' => '79520070', '137' => '79320075',
|
651
|
+
'138' => '61120286', '139' => '66020286', '140' => '79020076',
|
652
|
+
'142' => '64020186', '143' => '60020290', '144' => '79020076',
|
653
|
+
'145' => '66020286', '146' => '72120078', '147' => '72223182',
|
654
|
+
'148' => '76520071', '149' => '79020076', '150' => '76020070',
|
655
|
+
'151' => '76320072', '152' => '78320076', '154' => '70020270',
|
656
|
+
'155' => '76520071', '156' => '76020070', '157' => '10020890',
|
657
|
+
'158' => '70020270', '159' => '54520194', '160' => '70020270',
|
658
|
+
'161' => '54520194', '162' => '70020270', '163' => '70020270',
|
659
|
+
'164' => '70020270', '166' => '71120078', '167' => '74320073',
|
660
|
+
'167' => '74320073', '168' => '70320090', '169' => '79020076',
|
661
|
+
'170' => '70020270', '172' => '70020270', '174' => '70020270',
|
662
|
+
'175' => '72120078', '176' => '74020074', '177' => '74320073',
|
663
|
+
'178' => '70020270', '181' => '77320072', '182' => '79520070',
|
664
|
+
'183' => '70020270', '185' => '70020270', '186' => '79020076',
|
665
|
+
'188' => '70020270', '189' => '70020270', '190' => '76020070',
|
666
|
+
'191' => '77020070', '192' => '70025175', '193' => '85020086',
|
667
|
+
'194' => '76020070', '196' => '72020070', '198' => '76320072',
|
668
|
+
'199' => '70020270', '201' => '76020070', '202' => '76020070',
|
669
|
+
'203' => '76020070', '204' => '76020070', '205' => '79520070',
|
670
|
+
'206' => '79520070', '207' => '71120078', '208' => '73120075',
|
671
|
+
'209' => '18020086', '210' => '10020890', '211' => '60020290',
|
672
|
+
'212' => '51020186', '214' => '75020073', '215' => '63020086',
|
673
|
+
'216' => '75020073', '217' => '79020076', '218' => '59020090',
|
674
|
+
'219' => '79520070', '220' => '73322380', '221' => '73120075',
|
675
|
+
'222' => '73421478', '223' => '74320073', '224' => '73322380',
|
676
|
+
'225' => '74020074', '227' => '75020073', '228' => '71120078',
|
677
|
+
'229' => '80020086', '230' => '72120078', '231' => '72020070',
|
678
|
+
'232' => '75021174', '233' => '71020072', '234' => '71022182',
|
679
|
+
'235' => '74320073', '236' => '71022182', '237' => '76020070',
|
680
|
+
'238' => '63020086', '239' => '70020270', '240' => '75320075',
|
681
|
+
'241' => '76220073', '243' => '72020070', '245' => '72120078',
|
682
|
+
'246' => '74320073', '247' => '60020290', '248' => '85020086',
|
683
|
+
'249' => '73321177', '250' => '73420071', '251' => '70020270',
|
684
|
+
'252' => '70020270', '253' => '70020270', '254' => '10020890',
|
685
|
+
'255' => '50820292', '256' => '71022182', '257' => '83020086',
|
686
|
+
'258' => '79320075', '259' => '71120077', '260' => '10020890',
|
687
|
+
'261' => '70025175', '262' => '72020070', '264' => '74020074',
|
688
|
+
'267' => '63020086', '268' => '70320090', '269' => '71122183',
|
689
|
+
'270' => '82020086', '271' => '75020073', '272' => '73420071',
|
690
|
+
'274' => '63020086', '276' => '70020270', '277' => '74320073',
|
691
|
+
'278' => '71120077', '279' => '10020890', '281' => '71120078',
|
692
|
+
'282' => '70020270', '283' => '72020070', '284' => '79320075',
|
693
|
+
'286' => '54520194', '287' => '70020270', '288' => '75220070',
|
694
|
+
'291' => '77320072', '292' => '76020070', '293' => '72020070',
|
695
|
+
'294' => '54520194', '295' => '70020270', '296' => '70020270',
|
696
|
+
'299' => '72020070', '301' => '85020086', '302' => '54520194',
|
697
|
+
'304' => '70020270', '308' => '70020270', '309' => '54520194',
|
698
|
+
'310' => '72020070', '312' => '74120071', '313' => '76320072',
|
699
|
+
'314' => '70020270', '315' => '70020270', '316' => '70020270',
|
700
|
+
'317' => '70020270', '318' => '70020270', '320' => '71022182',
|
701
|
+
'321' => '75220070', '322' => '79520070', '324' => '70020270',
|
702
|
+
'326' => '85020086', '327' => '72020070', '328' => '72020070',
|
703
|
+
'329' => '70020270', '330' => '76020070', '331' => '70020270',
|
704
|
+
'333' => '70020270', '334' => '75020073', '335' => '70020270',
|
705
|
+
'337' => '80020086', '341' => '10020890', '342' => '10020890',
|
706
|
+
'344' => '70020270', '345' => '77020070', '346' => '76020070',
|
707
|
+
'350' => '79320075', '351' => '79320075', '352' => '70020270',
|
708
|
+
'353' => '70020270', '354' => '72223182', '355' => '72020070',
|
709
|
+
'356' => '70020270', '358' => '54220091', '359' => '76220073',
|
710
|
+
'360' => '80020087', '361' => '70020270', '362' => '70020270',
|
711
|
+
'363' => '70020270', '366' => '72220074', '367' => '70020270',
|
712
|
+
'368' => '10020890', '369' => '76520071', '370' => '85020086',
|
713
|
+
'371' => '70020270', '373' => '70020270', '374' => '73120075',
|
714
|
+
'375' => '70020270', '379' => '70020270', '380' => '70020270',
|
715
|
+
'381' => '70020270', '382' => '79520070', '383' => '72020070',
|
716
|
+
'384' => '72020070', '386' => '70020270', '387' => '70020270',
|
717
|
+
'389' => '70020270', '390' => '67020190', '391' => '70020270',
|
718
|
+
'392' => '70020270', '393' => '54520194', '394' => '70020270',
|
719
|
+
'396' => '70020270', '398' => '66020286', '399' => '87020088',
|
720
|
+
'401' => '30220190', '402' => '36020186', '403' => '38020090',
|
721
|
+
'404' => '30220190', '405' => '68020186', '406' => '48020086',
|
722
|
+
'407' => '37020090', '408' => '68020186', '409' => '10020890',
|
723
|
+
'410' => '66020286', '411' => '60420186', '412' => '57020086',
|
724
|
+
'422' => '70020270', '423' => '70020270', '424' => '76020070',
|
725
|
+
'426' => '70025175', '427' => '50320191', '428' => '70020270',
|
726
|
+
'429' => '85020086', '432' => '70020270', '434' => '60020290',
|
727
|
+
'435' => '76020070', '436' => '76020070', '437' => '70020270',
|
728
|
+
'438' => '70020270', '439' => '70020270', '440' => '70020270',
|
729
|
+
'441' => '70020270', '442' => '85020086', '443' => '55020486',
|
730
|
+
'444' => '50520190', '446' => '80020086', '447' => '70020270',
|
731
|
+
'450' => '30220190', '451' => '44020090', '452' => '70020270',
|
732
|
+
'453' => '70020270', '456' => '10020890', '457' => '87020086',
|
733
|
+
'458' => '54520194', '459' => '61120286', '460' => '70020270',
|
734
|
+
'461' => '70020270', '462' => '70020270', '463' => '70020270',
|
735
|
+
'465' => '70020270', '466' => '10020890', '467' => '10020890',
|
736
|
+
'468' => '70020270', '469' => '60320291', '470' => '65020186',
|
737
|
+
'471' => '84020087', '472' => '76020070', '473' => '74020074',
|
738
|
+
'476' => '78320076', '477' => '78320076', '478' => '87020088',
|
739
|
+
'480' => '70020270', '481' => '70020270', '482' => '84020087',
|
740
|
+
'484' => '70020270', '485' => '50320191', '486' => '70020270',
|
741
|
+
'488' => '67220286', '489' => '10020890', '490' => '10020890',
|
742
|
+
'491' => '16020086', '492' => '10020890', '494' => '79020076',
|
743
|
+
'495' => '87020088', '497' => '87020087', '499' => '79020076',
|
744
|
+
'502' => '10020890', '503' => '10020890', '505' => '70020270',
|
745
|
+
'506' => '10020890', '507' => '87020086', '508' => '86020086',
|
746
|
+
'509' => '83020087', '510' => '80020086', '511' => '83020086',
|
747
|
+
'513' => '85020086', '515' => '17020086', '518' => '82020086',
|
748
|
+
'519' => '83020086', '522' => '10020890', '523' => '70020270',
|
749
|
+
'524' => '85020086', '525' => '70020270', '527' => '82020088',
|
750
|
+
'528' => '10020890', '530' => '10020890', '531' => '10020890',
|
751
|
+
'533' => '50320191', '534' => '70020270', '536' => '85020086',
|
752
|
+
'538' => '82020086', '540' => '65020186', '541' => '80020087',
|
753
|
+
'545' => '18020086', '546' => '10020890', '547' => '10020890',
|
754
|
+
'548' => '10020890', '549' => '82020087', '555' => '79020076',
|
755
|
+
'560' => '79320075', '567' => '86020086', '572' => '10020890',
|
756
|
+
'580' => '70020270', '581' => '70020270', '601' => '74320073',
|
757
|
+
'602' => '70020270', '603' => '70020270', '604' => '70020270',
|
758
|
+
'605' => '70020270', '606' => '70020270', '607' => '74320073',
|
759
|
+
'608' => '72020070', '609' => '72020070', '610' => '72020070',
|
760
|
+
'611' => '72020070', '612' => '71120077', '613' => '70020270',
|
761
|
+
'614' => '72020070', '615' => '70025175', '616' => '73420071',
|
762
|
+
'617' => '68020186', '618' => '73120075', '619' => '60020290',
|
763
|
+
'620' => '71120077', '621' => '71120077', '622' => '74320073',
|
764
|
+
'623' => '72020070', '624' => '71020072', '625' => '71023173',
|
765
|
+
'626' => '71020072', '627' => '71021270', '628' => '71120077',
|
766
|
+
'629' => '73120075', '630' => '71121176', '631' => '71022182',
|
767
|
+
'632' => '70020270', '633' => '74320073', '634' => '70020270',
|
768
|
+
'635' => '70320090', '636' => '70320090', '637' => '72120078',
|
769
|
+
'638' => '72120078', '640' => '70020270', '641' => '70020270',
|
770
|
+
'643' => '74320073', '644' => '70020270', '645' => '70020270',
|
771
|
+
'646' => '70020270', '647' => '70020270', '648' => '72120078',
|
772
|
+
'649' => '72122181', '650' => '54520194', '652' => '71021270',
|
773
|
+
'653' => '70020270', '654' => '70020270', '655' => '72120078',
|
774
|
+
'656' => '71120078', '657' => '71020072', '658' => '68020186',
|
775
|
+
'659' => '54520194', '660' => '54620093', '661' => '74320073',
|
776
|
+
'662' => '73120075', '663' => '70322192', '664' => '72120078',
|
777
|
+
'665' => '70321194', '666' => '73322380', '667' => '60020290',
|
778
|
+
'668' => '60020290', '669' => '73320073', '670' => '75020073',
|
779
|
+
'671' => '74220075', '672' => '74020074', '673' => '74020074',
|
780
|
+
'674' => '74120071', '675' => '74020074', '676' => '74020074',
|
781
|
+
'677' => '72020070', '678' => '72020070', '679' => '54520194',
|
782
|
+
'680' => '71120077', '681' => '67020190', '682' => '78020070',
|
783
|
+
'683' => '71020072', '684' => '70020270', '685' => '70020270',
|
784
|
+
'686' => '70020270', '687' => '70020270', '688' => '70020270',
|
785
|
+
'689' => '70020270', '690' => '76520071', '692' => '70020270',
|
786
|
+
'693' => '73420071', '694' => '70021180', '695' => '70320090',
|
787
|
+
'696' => '74320073', '697' => '54020090', '698' => '73320073',
|
788
|
+
'710' => '30220190', '711' => '70020270', '712' => '10020890',
|
789
|
+
'714' => '76020070', '715' => '75020073', '717' => '74320073',
|
790
|
+
'718' => '87020086', '719' => '37020090', '720' => '30220190',
|
791
|
+
'723' => '77320072', '733' => '83020087', '798' => '70020270'
|
792
|
+
}.freeze
|
793
|
+
end
|
794
|
+
|
795
|
+
class Rule003200 < BaseRule
|
796
|
+
def converted_details
|
797
|
+
if @account_number.to_i.between?(800000000, 899999999)
|
798
|
+
msg = 'Account does not support payment transactions'
|
799
|
+
raise UnsupportedAccountDetails, msg
|
800
|
+
end
|
801
|
+
|
802
|
+
updated_bank_code = Rule003101::BANK_CODE_MAPPING.fetch(
|
803
|
+
@account_number.rjust(10, '0').slice(0, 3),
|
804
|
+
@bank_code
|
805
|
+
)
|
806
|
+
|
807
|
+
{ bank_code: updated_bank_code, account_number: @account_number }
|
808
|
+
end
|
809
|
+
end
|
810
|
+
|
811
|
+
class Rule003301 < BaseRule
|
812
|
+
PSEUDO_ACCOUNT_NUMBER_MAPPING = {
|
813
|
+
'0000022222' => '5803435253',
|
814
|
+
'0001111111' => '0039908140',
|
815
|
+
'0000000094' => '0002711931',
|
816
|
+
'0007777777' => '5800522694',
|
817
|
+
'0000055555' => '5801800000'
|
818
|
+
}.freeze
|
819
|
+
|
820
|
+
def converted_details
|
821
|
+
updated_bank_code = Rule003101::BANK_CODE_MAPPING.fetch(
|
822
|
+
@account_number.rjust(10, '0').slice(0, 3),
|
823
|
+
@bank_code
|
824
|
+
)
|
825
|
+
|
826
|
+
updated_account_number = PSEUDO_ACCOUNT_NUMBER_MAPPING.fetch(
|
827
|
+
@account_number.rjust(10, '0'),
|
828
|
+
@account_number
|
829
|
+
)
|
830
|
+
|
831
|
+
{ bank_code: updated_bank_code, account_number: updated_account_number }
|
832
|
+
end
|
833
|
+
end
|
834
|
+
|
835
|
+
class Rule003400 < BaseRule
|
836
|
+
PSEUDO_ACCOUNT_NUMBER_MAPPING = {
|
837
|
+
'0500500500' => '4340111112',
|
838
|
+
'0000000502' => '4340118001'
|
839
|
+
}.freeze
|
840
|
+
|
841
|
+
def converted_details
|
842
|
+
if @account_number.to_i.between?(800000000, 899999999)
|
843
|
+
msg = 'Account does not support payment transactions'
|
844
|
+
raise UnsupportedAccountDetails, msg
|
845
|
+
end
|
846
|
+
|
847
|
+
updated_bank_code = Rule003101::BANK_CODE_MAPPING.fetch(
|
848
|
+
@account_number.rjust(10, '0').slice(0, 3),
|
849
|
+
@bank_code
|
850
|
+
)
|
851
|
+
|
852
|
+
updated_account_number = PSEUDO_ACCOUNT_NUMBER_MAPPING.fetch(
|
853
|
+
@account_number.rjust(10, '0'),
|
854
|
+
@account_number
|
855
|
+
)
|
856
|
+
|
857
|
+
{ bank_code: updated_bank_code, account_number: updated_account_number }
|
858
|
+
end
|
859
|
+
end
|
860
|
+
|
861
|
+
class Rule003501 < BaseRule
|
862
|
+
PSEUDO_ACCOUNT_NUMBER_MAPPING = { '0000009696' => '1490196966' }.freeze
|
863
|
+
|
864
|
+
def converted_details
|
865
|
+
if @account_number.to_i.between?(800000000, 899999999)
|
866
|
+
msg = 'Account does not support payment transactions'
|
867
|
+
raise UnsupportedAccountDetails, msg
|
868
|
+
end
|
869
|
+
|
870
|
+
updated_bank_code = Rule003101::BANK_CODE_MAPPING.fetch(
|
871
|
+
@account_number.rjust(10, '0').slice(0, 3),
|
872
|
+
@bank_code
|
873
|
+
)
|
874
|
+
|
875
|
+
updated_account_number = PSEUDO_ACCOUNT_NUMBER_MAPPING.fetch(
|
876
|
+
@account_number.rjust(10, '0'),
|
877
|
+
@account_number
|
878
|
+
)
|
879
|
+
|
880
|
+
{ bank_code: updated_bank_code, account_number: updated_account_number }
|
881
|
+
end
|
882
|
+
end
|
883
|
+
|
884
|
+
class Rule003600 < BaseRule
|
885
|
+
def converted_details
|
886
|
+
updated_account_number =
|
887
|
+
case @account_number.to_i
|
888
|
+
when 100000..899999 then @account_number + '000'
|
889
|
+
when 30000000..59999999 then @account_number
|
890
|
+
when 100000000..899999999 then @account_number
|
891
|
+
when 1000000000..1999999999 then @account_number
|
892
|
+
when 3000000000..7099999999 then @account_number
|
893
|
+
when 8500000000..8599999999 then @account_number
|
894
|
+
when 9000000000..9999999999 then @account_number
|
895
|
+
else disallow
|
896
|
+
end
|
897
|
+
|
898
|
+
{ bank_code: '20050000', account_number: updated_account_number }
|
899
|
+
end
|
900
|
+
|
901
|
+
private
|
902
|
+
|
903
|
+
def disallow
|
904
|
+
msg = 'Account does not support payment transactions'
|
905
|
+
raise UnsupportedAccountDetails, msg
|
906
|
+
end
|
907
|
+
end
|
908
|
+
|
909
|
+
class Rule003700 < BaseRule
|
910
|
+
def converted_details
|
911
|
+
{ bank_code: '30010700', account_number: @account_number }
|
912
|
+
end
|
913
|
+
end
|
914
|
+
|
915
|
+
class Rule003800 < BaseRule
|
916
|
+
def converted_details
|
917
|
+
{ bank_code: '28590075', account_number: @account_number }
|
918
|
+
end
|
919
|
+
end
|
920
|
+
|
921
|
+
class Rule003900 < BaseRule
|
922
|
+
def converted_details
|
923
|
+
{ bank_code: '28020050', account_number: @account_number }
|
924
|
+
end
|
925
|
+
end
|
926
|
+
|
927
|
+
class Rule004001 < BaseRule
|
928
|
+
def converted_details
|
929
|
+
{ bank_code: '68052328', account_number: @account_number }
|
930
|
+
end
|
931
|
+
end
|
932
|
+
|
933
|
+
class Rule004100 < BaseRule
|
934
|
+
def converted_details
|
935
|
+
{ bank_code: '50060400', account_number: '0000011404' }
|
936
|
+
end
|
937
|
+
end
|
938
|
+
|
939
|
+
class Rule004200 < BaseRule
|
940
|
+
def converted_details
|
941
|
+
unpadded_account_number = @account_number.gsub(/\A0+/, '')
|
942
|
+
|
943
|
+
if @account_number.to_i.between?(50462000, 50463999) ||
|
944
|
+
@account_number.to_i.between?(50469000, 50469999)
|
945
|
+
{ bank_code: @bank_code, account_number: @account_number }
|
946
|
+
elsif unpadded_account_number.size != 8 ||
|
947
|
+
unpadded_account_number[3] != '0' ||
|
948
|
+
%w(00000 00999).include?(unpadded_account_number.slice(3, 5))
|
949
|
+
msg = 'Account does not support payment transactions'
|
950
|
+
raise UnsupportedAccountDetails, msg
|
951
|
+
else
|
952
|
+
{ bank_code: @bank_code, account_number: @account_number }
|
953
|
+
end
|
954
|
+
end
|
955
|
+
end
|
956
|
+
|
957
|
+
class Rule004301 < BaseRule
|
958
|
+
def converted_details
|
959
|
+
{ bank_code: '66650085', account_number: @account_number }
|
960
|
+
end
|
961
|
+
end
|
962
|
+
|
963
|
+
class Rule004400 < BaseRule
|
964
|
+
include PseudoAccountNumberBehaviour
|
965
|
+
|
966
|
+
@pseudo_account_number_mapping = { '0000000202' => '0002282022' }
|
967
|
+
end
|
968
|
+
|
969
|
+
class Rule004501 < Rule000000
|
970
|
+
# Rule 004501 is actually about BICs, and the BIC details are already
|
971
|
+
# included correctly in the Bankleitzahl file and SWIFT databases
|
972
|
+
end
|
973
|
+
|
974
|
+
class Rule004600 < BaseRule
|
975
|
+
def converted_details
|
976
|
+
{ bank_code: '31010833', account_number: @account_number }
|
977
|
+
end
|
978
|
+
end
|
979
|
+
|
980
|
+
class Rule004700 < BaseRule
|
981
|
+
def converted_details
|
982
|
+
unpadded_account_number = @account_number.gsub(/\A0+/, '')
|
983
|
+
|
984
|
+
updated_account_number =
|
985
|
+
if unpadded_account_number.size == 8
|
986
|
+
unpadded_account_number.ljust(10, '0')
|
987
|
+
else
|
988
|
+
unpadded_account_number.rjust(10, '0')
|
989
|
+
end
|
990
|
+
|
991
|
+
{ bank_code: @bank_code, account_number: updated_account_number }
|
992
|
+
end
|
993
|
+
end
|
994
|
+
|
995
|
+
class Rule004800 < BaseRule
|
996
|
+
def converted_details
|
997
|
+
{ bank_code: '36010200', account_number: @account_number }
|
998
|
+
end
|
999
|
+
end
|
1000
|
+
|
1001
|
+
class Rule004900 < BaseRule
|
1002
|
+
PSEUDO_ACCOUNT_NUMBER_MAPPING = {
|
1003
|
+
'0000000036' => '0002310113',
|
1004
|
+
'0000000936' => '0002310113',
|
1005
|
+
'0000000999' => '0001310113',
|
1006
|
+
'0000006060' => '0000160602'
|
1007
|
+
}.freeze
|
1008
|
+
|
1009
|
+
def converted_details
|
1010
|
+
padded_account_number = @account_number.rjust(10, '0')
|
1011
|
+
|
1012
|
+
updated_account_number =
|
1013
|
+
if padded_account_number[4] == '9'
|
1014
|
+
"#{padded_account_number[4, 6]}#{padded_account_number[0, 4]}"
|
1015
|
+
else
|
1016
|
+
@account_number
|
1017
|
+
end
|
1018
|
+
|
1019
|
+
updated_account_number = PSEUDO_ACCOUNT_NUMBER_MAPPING.fetch(
|
1020
|
+
updated_account_number.rjust(10, '0'),
|
1021
|
+
updated_account_number
|
1022
|
+
)
|
1023
|
+
|
1024
|
+
{ bank_code: @bank_code, account_number: updated_account_number }
|
1025
|
+
end
|
1026
|
+
end
|
1027
|
+
|
1028
|
+
class Rule005000 < BaseRule
|
1029
|
+
def converted_details
|
1030
|
+
{ bank_code: '28550000', account_number: @account_number }
|
1031
|
+
end
|
1032
|
+
end
|
1033
|
+
|
1034
|
+
class Rule005100 < BaseRule
|
1035
|
+
include PseudoAccountNumberBehaviour
|
1036
|
+
|
1037
|
+
@pseudo_account_number_mapping = {
|
1038
|
+
'0000000333' => '7832500881',
|
1039
|
+
'0000000502' => '0001108884',
|
1040
|
+
'0500500500' => '0005005000',
|
1041
|
+
'0502502502' => '0001108884'
|
1042
|
+
}
|
1043
|
+
end
|
1044
|
+
|
1045
|
+
class Rule005200 < BaseRule
|
1046
|
+
PSEUDO_ACCOUNT_NUMBER_MAPPING = {
|
1047
|
+
'67220020_5308810004' => '0002662604',
|
1048
|
+
'67220020_5308810000' => '0002659600',
|
1049
|
+
'67020020_5203145700' => '7496510994',
|
1050
|
+
'69421020_6208908100' => '7481501341',
|
1051
|
+
'66620020_4840404000' => '7498502663',
|
1052
|
+
'64120030_1201200100' => '7477501214',
|
1053
|
+
'64020030_1408050100' => '7469534505',
|
1054
|
+
'63020130_1112156300' => '0004475655',
|
1055
|
+
'62030050_7002703200' => '7406501175',
|
1056
|
+
'69220020_6402145400' => '7485500252'
|
1057
|
+
}.freeze
|
1058
|
+
|
1059
|
+
def converted_details
|
1060
|
+
updated_account_number = PSEUDO_ACCOUNT_NUMBER_MAPPING.fetch(
|
1061
|
+
"#{@bank_code}_#{@account_number.rjust(10, '0')}",
|
1062
|
+
nil
|
1063
|
+
)
|
1064
|
+
|
1065
|
+
if updated_account_number.nil?
|
1066
|
+
msg = "Bank code #{@bank_code} is not used for payment transactions"
|
1067
|
+
raise UnsupportedAccountDetails, msg
|
1068
|
+
end
|
1069
|
+
|
1070
|
+
{ bank_code: '60050101', account_number: updated_account_number }
|
1071
|
+
end
|
1072
|
+
end
|
1073
|
+
|
1074
|
+
class Rule005300 < BaseRule
|
1075
|
+
PSEUDO_ACCOUNT_NUMBER_MAPPING = {
|
1076
|
+
'55050000_0000035000' => '7401555913',
|
1077
|
+
'55050000_0119345106' => '7401555906',
|
1078
|
+
'55050000_0000000908' => '7401507480',
|
1079
|
+
'55050000_0000000901' => '7401507497',
|
1080
|
+
'55050000_0000000910' => '7401507466',
|
1081
|
+
'55050000_0000035100' => '7401555913',
|
1082
|
+
'55050000_0000000902' => '7401507473',
|
1083
|
+
'55050000_0000044000' => '7401555872',
|
1084
|
+
'55050000_0110132511' => '7401550530',
|
1085
|
+
'55050000_0110024270' => '7401501266',
|
1086
|
+
'55050000_0000003500' => '7401555913',
|
1087
|
+
'55050000_0110050002' => '7401502234',
|
1088
|
+
'55050000_0055020100' => '7401555872',
|
1089
|
+
'55050000_0110149226' => '7401512248',
|
1090
|
+
'60020030_1047444300' => '7871538395',
|
1091
|
+
'60020030_1040748400' => '0001366705',
|
1092
|
+
'60020030_1000617900' => '0002009906',
|
1093
|
+
'60020030_1003340500' => '0002001155',
|
1094
|
+
'60020030_1002999900' => '0002588991',
|
1095
|
+
'60020030_1004184600' => '7871513509',
|
1096
|
+
'60020030_1000919900' => '7871531505',
|
1097
|
+
'60020030_1054290000' => '7871521216',
|
1098
|
+
'60050000_0000001523' => '0001364934',
|
1099
|
+
'60050000_0000002811' => '0001367450',
|
1100
|
+
'60050000_0000002502' => '0001366705',
|
1101
|
+
'60050000_0000250412' => '7402051588',
|
1102
|
+
'60050000_0000003009' => '0001367924',
|
1103
|
+
'60050000_0000004596' => '0001372809',
|
1104
|
+
'60050000_0000003080' => '0002009906',
|
1105
|
+
'60050000_0001029204' => '0002782254',
|
1106
|
+
'60050000_0000003002' => '0001367924',
|
1107
|
+
'60050000_0000123456' => '0001362826',
|
1108
|
+
'60050000_0000002535' => '0001119897',
|
1109
|
+
'60050000_0000005500' => '0001375703',
|
1110
|
+
'66020020_4002401000' => '7495500967',
|
1111
|
+
'66020020_4000604100' => '0002810030',
|
1112
|
+
'66020020_4002015800' => '7495530102',
|
1113
|
+
'66020020_4003746700' => '7495501485',
|
1114
|
+
'66050000_0000086567' => '0001364934',
|
1115
|
+
'66050000_0000086345' => '7402046641',
|
1116
|
+
'66050000_0000085304' => '7402045439',
|
1117
|
+
'66050000_0000085990' => '7402051588',
|
1118
|
+
'86050000_0000001016' => '7461500128',
|
1119
|
+
'86050000_0000003535' => '7461505611',
|
1120
|
+
'86050000_0000002020' => '7461500018',
|
1121
|
+
'86050000_0000004394' => '7461505714'
|
1122
|
+
}.freeze
|
1123
|
+
|
1124
|
+
def converted_details
|
1125
|
+
updated_account_number = PSEUDO_ACCOUNT_NUMBER_MAPPING.fetch(
|
1126
|
+
"#{@bank_code}_#{@account_number.rjust(10, '0')}",
|
1127
|
+
nil
|
1128
|
+
)
|
1129
|
+
|
1130
|
+
{
|
1131
|
+
bank_code: updated_account_number.nil? ? @bank_code : '60050101',
|
1132
|
+
account_number: updated_account_number || @account_number
|
1133
|
+
}
|
1134
|
+
end
|
1135
|
+
end
|
1136
|
+
|
1137
|
+
class Rule005401 < BaseRule
|
1138
|
+
include PseudoAccountNumberBehaviour
|
1139
|
+
|
1140
|
+
@pseudo_account_number_mapping = {
|
1141
|
+
'0000000500' => '0000500500',
|
1142
|
+
'0000000502' => '0000502502',
|
1143
|
+
'0000018067' => '0000180670',
|
1144
|
+
'0000484848' => '0000484849',
|
1145
|
+
'0000636306' => '0000063606',
|
1146
|
+
'0000760440' => '0000160440',
|
1147
|
+
'0001018413' => '0010108413',
|
1148
|
+
'0002601577' => '0026015776',
|
1149
|
+
'0005005000' => '0000500500',
|
1150
|
+
'0010796740' => '0010796743',
|
1151
|
+
'0011796740' => '0011796743',
|
1152
|
+
'0012796740' => '0012796743',
|
1153
|
+
'0013796740' => '0013796743',
|
1154
|
+
'0014796740' => '0014796743',
|
1155
|
+
'0015796740' => '0015796743',
|
1156
|
+
'0016307000' => '0163107000',
|
1157
|
+
'0016610700' => '0166107000',
|
1158
|
+
'0016796740' => '0016796743',
|
1159
|
+
'0017796740' => '0017796743',
|
1160
|
+
'0018796740' => '0018796743',
|
1161
|
+
'0019796740' => '0019796743',
|
1162
|
+
'0020796740' => '0020796743',
|
1163
|
+
'0021796740' => '0021796743',
|
1164
|
+
'0022796740' => '0022796743',
|
1165
|
+
'0023796740' => '0023796743',
|
1166
|
+
'0024796740' => '0024796743',
|
1167
|
+
'0025796740' => '0025796743',
|
1168
|
+
'0026610700' => '0266107000',
|
1169
|
+
'0026796740' => '0026796743',
|
1170
|
+
'0027796740' => '0027796743',
|
1171
|
+
'0028796740' => '0028796743',
|
1172
|
+
'0029796740' => '0029796743',
|
1173
|
+
'0045796740' => '0045796743',
|
1174
|
+
'0050796740' => '0050796743',
|
1175
|
+
'0051796740' => '0051796743',
|
1176
|
+
'0052796740' => '0052796743',
|
1177
|
+
'0053796740' => '0053796743',
|
1178
|
+
'0054796740' => '0054796743',
|
1179
|
+
'0055796740' => '0055796743',
|
1180
|
+
'0056796740' => '0056796743',
|
1181
|
+
'0057796740' => '0057796743',
|
1182
|
+
'0058796740' => '0058796743',
|
1183
|
+
'0059796740' => '0059796743',
|
1184
|
+
'0060796740' => '0060796743',
|
1185
|
+
'0061796740' => '0061796743',
|
1186
|
+
'0062796740' => '0062796743',
|
1187
|
+
'0063796740' => '0063796743',
|
1188
|
+
'0064796740' => '0064796743',
|
1189
|
+
'0065796740' => '0065796743',
|
1190
|
+
'0066796740' => '0066796743',
|
1191
|
+
'0067796740' => '0067796743',
|
1192
|
+
'0068796740' => '0068796743',
|
1193
|
+
'0069796740' => '0069796743',
|
1194
|
+
'1761070000' => '0176107000',
|
1195
|
+
'2210531180' => '0201053180'
|
1196
|
+
}
|
1197
|
+
end
|
1198
|
+
|
1199
|
+
class Rule005500 < BaseRule
|
1200
|
+
def converted_details
|
1201
|
+
{ bank_code: '25410200', account_number: @account_number }
|
1202
|
+
end
|
1203
|
+
end
|
1204
|
+
|
1205
|
+
class Rule005600 < BaseRule
|
1206
|
+
EXCEPTION_BANK_CODES = %w(
|
1207
|
+
10010111 26510111 36210111 48010111 59010111 70010111 13010111 27010111
|
1208
|
+
37010111 50010111 60010111 72010111 16010111 28010111 38010111 50510111
|
1209
|
+
63010111 75010111 20010111 29010111 39010111 51010111 65310111 76010111
|
1210
|
+
21010111 29210111 40010111 51310111 66010111 79010111 21210111 30010111
|
1211
|
+
41010111 51410111 66610111 79510111 23010111 31010111 42010111 52010111
|
1212
|
+
67010111 81010111 25010111 33010111 42610112 54210111 67210111 82010111
|
1213
|
+
25410111 35010111 43010111 55010111 68010111 86010111 25910111 35211012
|
1214
|
+
44010111 57010111 68310111 26010111 36010111 46010111 58510111 69010111
|
1215
|
+
).freeze
|
1216
|
+
|
1217
|
+
PSEUDO_ACCOUNT_NUMBER_MAPPING = {
|
1218
|
+
'0000000036' => '1010240003',
|
1219
|
+
'0000000050' => '1328506100',
|
1220
|
+
'0000000099' => '1826063000',
|
1221
|
+
'0000000110' => '1015597802',
|
1222
|
+
'0000000240' => '1010240000',
|
1223
|
+
'0000000333' => '1011296100',
|
1224
|
+
'0000000555' => '1600220800',
|
1225
|
+
'0000000556' => '1000556100',
|
1226
|
+
'0000000606' => '1967153801',
|
1227
|
+
'0000000700' => '1070088000',
|
1228
|
+
'0000000777' => '1006015200',
|
1229
|
+
'0000000999' => '1010240001',
|
1230
|
+
'0000001234' => '1369152400',
|
1231
|
+
'0000001313' => '1017500000',
|
1232
|
+
'0000001888' => '1241113000',
|
1233
|
+
'0000001953' => '1026500901',
|
1234
|
+
'0000001998' => '1547620500',
|
1235
|
+
'0000002007' => '1026500907',
|
1236
|
+
'0000004004' => '1635100100',
|
1237
|
+
'0000004444' => '1304610900',
|
1238
|
+
'0000005000' => '1395676000',
|
1239
|
+
'0000005510' => '1611754300',
|
1240
|
+
'0000006060' => '1000400200',
|
1241
|
+
'0000006800' => '1296401301',
|
1242
|
+
'0000055555' => '1027758200',
|
1243
|
+
'0000060000' => '1005007001',
|
1244
|
+
'0000066666' => '1299807801',
|
1245
|
+
'0000102030' => '1837501600',
|
1246
|
+
'0000121212' => '1249461502',
|
1247
|
+
'0000130500' => '1413482100',
|
1248
|
+
'0000202020' => '1213431002',
|
1249
|
+
'0000414141' => '1010555101',
|
1250
|
+
'0000666666' => '1798758900',
|
1251
|
+
'0005000000' => '1403124100',
|
1252
|
+
'0500500500' => '1045720000'
|
1253
|
+
}.freeze
|
1254
|
+
|
1255
|
+
def converted_details
|
1256
|
+
updated_account_number = PSEUDO_ACCOUNT_NUMBER_MAPPING.fetch(
|
1257
|
+
@account_number.rjust(10, '0'),
|
1258
|
+
@account_number
|
1259
|
+
)
|
1260
|
+
|
1261
|
+
if updated_account_number.gsub(/\A0+/, '').size < 10 &&
|
1262
|
+
EXCEPTION_BANK_CODES.include?(@bank_code)
|
1263
|
+
msg = 'Account does not support payment transactions'
|
1264
|
+
raise UnsupportedAccountDetails, msg
|
1265
|
+
end
|
1266
|
+
|
1267
|
+
{ bank_code: @bank_code, account_number: updated_account_number }
|
1268
|
+
end
|
1269
|
+
end
|
1270
|
+
|
1271
|
+
class Rule005700 < BaseRule
|
1272
|
+
def converted_details
|
1273
|
+
{ bank_code: '66010200', account_number: @account_number }
|
1274
|
+
end
|
1275
|
+
end
|
1276
|
+
end
|
1277
|
+
end
|