ibandit 0.1.1 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|