ibandit 1.0.0 → 1.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/.circleci/config.yml +37 -0
- data/.rubocop.yml +10 -5
- data/.rubocop_todo.yml +13 -12
- data/CHANGELOG.md +23 -0
- data/Gemfile +0 -4
- data/README.md +1 -1
- data/Rakefile +8 -0
- data/data/german_iban_rules.yml +1099 -1594
- data/data/raw/BLZ2.txt +15947 -17888
- data/data/structures.yml +2 -2
- data/ibandit.gemspec +3 -2
- data/lib/ibandit.rb +1 -1
- data/lib/ibandit/check_digit.rb +1 -1
- data/lib/ibandit/german_details_converter.rb +22 -1
- data/lib/ibandit/iban.rb +20 -9
- data/lib/ibandit/local_details_cleaner.rb +7 -5
- data/lib/ibandit/version.rb +1 -1
- data/spec/fixtures/germany_integration_test_cases.json +23 -17
- data/spec/fixtures/germany_unit_test_cases.json +31 -6
- data/spec/ibandit/iban_spec.rb +27 -4
- data/spec/ibandit/local_details_cleaner_spec.rb +7 -1
- data/spec/ibandit/pseudo_iban_assembler_spec.rb +1 -1
- data/spec/ibandit/structure_spec.rb +1 -1
- metadata +22 -7
- data/.travis.yml +0 -16
data/data/structures.yml
CHANGED
@@ -95,7 +95,7 @@ BE:
|
|
95
95
|
:national_id_length: 3
|
96
96
|
:bban_format: "\\d{3}\\d{7}\\d{2}"
|
97
97
|
:bank_code_format: "\\d{3}"
|
98
|
-
:account_number_format: "\\d{7}\\d{2}"
|
98
|
+
:account_number_format: "\\d{7}\\d{2}\\d{3}"
|
99
99
|
:local_check_digit_position: 15
|
100
100
|
:local_check_digit_length: 2
|
101
101
|
BG:
|
@@ -902,7 +902,7 @@ US:
|
|
902
902
|
:branch_code_length: 0
|
903
903
|
:account_number_length: 17
|
904
904
|
:bank_code_format: "\\d{9}"
|
905
|
-
:account_number_format: "
|
905
|
+
:account_number_format: "_*\\d{1,17}"
|
906
906
|
:national_id_length: 9
|
907
907
|
:pseudo_iban_bank_code_length: 9
|
908
908
|
:pseudo_iban_branch_code_length: 0
|
data/ibandit.gemspec
CHANGED
@@ -3,13 +3,14 @@
|
|
3
3
|
require File.expand_path("lib/ibandit/version", __dir__)
|
4
4
|
|
5
5
|
Gem::Specification.new do |gem|
|
6
|
+
gem.add_development_dependency "gc_ruboconfig", "~> 2.17.0"
|
6
7
|
gem.add_development_dependency "nokogiri", "~> 1.6"
|
7
8
|
gem.add_development_dependency "pry", "~> 0.10"
|
8
9
|
gem.add_development_dependency "pry-nav", "~> 0.2"
|
9
10
|
gem.add_development_dependency "rspec", "~> 3.3"
|
10
11
|
gem.add_development_dependency "rspec-its", "~> 1.2"
|
11
|
-
gem.add_development_dependency "
|
12
|
-
gem.add_development_dependency "sax-machine",
|
12
|
+
gem.add_development_dependency "rspec_junit_formatter", "~> 0.4.1"
|
13
|
+
gem.add_development_dependency "sax-machine", "~> 1.3"
|
13
14
|
|
14
15
|
gem.add_runtime_dependency "i18n"
|
15
16
|
|
data/lib/ibandit.rb
CHANGED
data/lib/ibandit/check_digit.rb
CHANGED
@@ -517,7 +517,7 @@ module Ibandit
|
|
517
517
|
updated_account_number =
|
518
518
|
case unpadded_account_number.size
|
519
519
|
when 5, 6 then unpadded_account_number + "00"
|
520
|
-
when 7
|
520
|
+
when 7
|
521
521
|
if Check63.new(unpadded_account_number + "00").valid?
|
522
522
|
unpadded_account_number + "00"
|
523
523
|
else
|
@@ -957,6 +957,23 @@ module Ibandit
|
|
957
957
|
end
|
958
958
|
end
|
959
959
|
|
960
|
+
# New version of Rule004200 but with another range:
|
961
|
+
# For 10-digit Account Numbers, only the following Account Numbers are
|
962
|
+
# applicable to be issued / created into an IBAN with the
|
963
|
+
# standard-IBAN rule: nnn4400001 to nnn4499999
|
964
|
+
class Rule004201 < Rule004200
|
965
|
+
def converted_details
|
966
|
+
unpadded_account_number = @account_number.gsub(/\A0+/, "")
|
967
|
+
|
968
|
+
if unpadded_account_number.size == 10 &&
|
969
|
+
%w[4400001 4499999].include?(unpadded_account_number.slice(3, 10))
|
970
|
+
{ bank_code: @bank_code, account_number: @account_number }
|
971
|
+
else
|
972
|
+
super
|
973
|
+
end
|
974
|
+
end
|
975
|
+
end
|
976
|
+
|
960
977
|
class Rule004301 < BaseRule
|
961
978
|
def converted_details
|
962
979
|
{ bank_code: "66650085", account_number: @account_number }
|
@@ -1028,6 +1045,10 @@ module Ibandit
|
|
1028
1045
|
end
|
1029
1046
|
end
|
1030
1047
|
|
1048
|
+
class Rule004901 < Rule000000
|
1049
|
+
# Rule 0049 01 is actually about modulus checking, not IBAN construction
|
1050
|
+
end
|
1051
|
+
|
1031
1052
|
class Rule005000 < BaseRule
|
1032
1053
|
def converted_details
|
1033
1054
|
{ bank_code: "28550000", account_number: @account_number }
|
data/lib/ibandit/iban.rb
CHANGED
@@ -9,7 +9,8 @@ module Ibandit
|
|
9
9
|
:swift_account_number, :source
|
10
10
|
|
11
11
|
def initialize(argument)
|
12
|
-
|
12
|
+
case argument
|
13
|
+
when String
|
13
14
|
input = argument.to_s.gsub(/\s+/, "").upcase
|
14
15
|
|
15
16
|
pseudo_iban_splitter = PseudoIBANSplitter.new(input)
|
@@ -24,7 +25,7 @@ module Ibandit
|
|
24
25
|
@iban = input
|
25
26
|
extract_swift_details_from_iban!
|
26
27
|
end
|
27
|
-
|
28
|
+
when Hash
|
28
29
|
@source = :local_details
|
29
30
|
build_iban_from_local_details(argument)
|
30
31
|
else
|
@@ -225,7 +226,7 @@ module Ibandit
|
|
225
226
|
return unless valid_country_code?
|
226
227
|
return unless structure[:bban_format]
|
227
228
|
|
228
|
-
if bban
|
229
|
+
if bban&.match?(entire_string_regex(structure[:bban_format]))
|
229
230
|
true
|
230
231
|
else
|
231
232
|
@errors[:format] = Ibandit.translate(:invalid_format,
|
@@ -238,7 +239,9 @@ module Ibandit
|
|
238
239
|
return unless valid_bank_code_length?
|
239
240
|
return true if structure[:bank_code_length]&.zero?
|
240
241
|
|
241
|
-
if swift_bank_code
|
242
|
+
if swift_bank_code&.match?(
|
243
|
+
entire_string_regex(structure[:bank_code_format]),
|
244
|
+
)
|
242
245
|
true
|
243
246
|
else
|
244
247
|
@errors[:bank_code] = Ibandit.translate(:is_invalid)
|
@@ -250,7 +253,9 @@ module Ibandit
|
|
250
253
|
return unless valid_branch_code_length?
|
251
254
|
return true unless structure[:branch_code_format]
|
252
255
|
|
253
|
-
if swift_branch_code
|
256
|
+
if swift_branch_code&.match?(
|
257
|
+
entire_string_regex(structure[:branch_code_format]),
|
258
|
+
)
|
254
259
|
true
|
255
260
|
else
|
256
261
|
@errors[:branch_code] = Ibandit.translate(:is_invalid)
|
@@ -261,7 +266,9 @@ module Ibandit
|
|
261
266
|
def valid_account_number_format?
|
262
267
|
return unless valid_account_number_length?
|
263
268
|
|
264
|
-
if swift_account_number
|
269
|
+
if swift_account_number&.match?(
|
270
|
+
entire_string_regex(structure[:account_number_format]),
|
271
|
+
)
|
265
272
|
true
|
266
273
|
else
|
267
274
|
@errors[:account_number] = Ibandit.translate(:is_invalid)
|
@@ -460,12 +467,12 @@ module Ibandit
|
|
460
467
|
@swift_branch_code = try_dup(local_details[:swift_branch_code])
|
461
468
|
@swift_bank_code = try_dup(local_details[:swift_bank_code])
|
462
469
|
|
463
|
-
@iban
|
470
|
+
@iban = IBANAssembler.assemble(swift_details)
|
464
471
|
|
465
472
|
if source == :pseudo_iban
|
466
|
-
@check_digits
|
473
|
+
@check_digits = try_dup(local_details[:check_digits])
|
467
474
|
else
|
468
|
-
@check_digits
|
475
|
+
@check_digits = @iban.slice(2, 2) unless @iban.nil?
|
469
476
|
end
|
470
477
|
end
|
471
478
|
|
@@ -497,6 +504,10 @@ module Ibandit
|
|
497
504
|
Ibandit.structures[country_code]
|
498
505
|
end
|
499
506
|
|
507
|
+
def entire_string_regex(pattern)
|
508
|
+
Regexp.new("\\A#{pattern}\\z")
|
509
|
+
end
|
510
|
+
|
500
511
|
def formatted
|
501
512
|
iban.to_s.gsub(/(.{4})/, '\1 ').strip
|
502
513
|
end
|
@@ -89,7 +89,9 @@ module Ibandit
|
|
89
89
|
end
|
90
90
|
|
91
91
|
def self.clean_ca_details(local_details)
|
92
|
-
|
92
|
+
account_number = local_details[:account_number].tr("-", "")
|
93
|
+
|
94
|
+
return {} if account_number.length < 7 # minimum length
|
93
95
|
|
94
96
|
bank_code = if local_details[:bank_code].length == 3
|
95
97
|
local_details[:bank_code].rjust(4, "0")
|
@@ -98,7 +100,7 @@ module Ibandit
|
|
98
100
|
end
|
99
101
|
|
100
102
|
{
|
101
|
-
account_number:
|
103
|
+
account_number: account_number.rjust(12, "0"),
|
102
104
|
bank_code: bank_code,
|
103
105
|
}
|
104
106
|
end
|
@@ -198,7 +200,7 @@ module Ibandit
|
|
198
200
|
bank_code, account_number = local_details[:account_number].split("-", 2)
|
199
201
|
elsif local_details[:account_number].gsub(/\s/, "").length == 14
|
200
202
|
cleaned_account_number = local_details[:account_number].gsub(/\s/, "")
|
201
|
-
bank_code
|
203
|
+
bank_code = cleaned_account_number.slice(0, 4)
|
202
204
|
account_number = cleaned_account_number.slice(4, 10)
|
203
205
|
else
|
204
206
|
return {}
|
@@ -512,7 +514,7 @@ module Ibandit
|
|
512
514
|
bank_code = local_details[:bank_code]
|
513
515
|
account_number = local_details[:account_number]
|
514
516
|
else
|
515
|
-
cleaned_acct_number = local_details[:account_number].gsub(
|
517
|
+
cleaned_acct_number = local_details[:account_number].gsub(/\s/, "")
|
516
518
|
|
517
519
|
bank_code = cleaned_acct_number.slice(2, 8)
|
518
520
|
account_number = cleaned_acct_number[10..-1]
|
@@ -573,7 +575,7 @@ module Ibandit
|
|
573
575
|
ken_1 = parts[2].nil? ? "" : parts[2].rjust(6, "0")
|
574
576
|
ken_2 = parts[3].nil? ? "" : parts[3].rjust(4, "0")
|
575
577
|
|
576
|
-
kennitala
|
578
|
+
kennitala = ken_1.empty? ? "" : (ken_1 + ken_2).rjust(10, "0")
|
577
579
|
|
578
580
|
hufo + reikningsnumer + kennitala
|
579
581
|
end
|
data/lib/ibandit/version.rb
CHANGED
@@ -22,15 +22,15 @@
|
|
22
22
|
{ "bank_code": "72020700", "account_number" : "1111111611" }
|
23
23
|
]
|
24
24
|
},
|
25
|
-
{
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
},
|
25
|
+
// {
|
26
|
+
// "convertor": "000300",
|
27
|
+
// "valid": [
|
28
|
+
// { "bank_code": "51010800", "account_number" : "1" }
|
29
|
+
// ],
|
30
|
+
// "invalid": [
|
31
|
+
// { "bank_code": "51010800", "account_number" : "6161604670" }
|
32
|
+
// ]
|
33
|
+
// },
|
34
34
|
{
|
35
35
|
"convertor": "000400",
|
36
36
|
"valid": [
|
@@ -101,12 +101,12 @@
|
|
101
101
|
{"bank_code":"51020000","account_number":"30009963","converted_bank_code":"50020200","converted_account_number":"30009963"}
|
102
102
|
]
|
103
103
|
},
|
104
|
-
{
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
},
|
104
|
+
// {
|
105
|
+
// "convertor": "000900",
|
106
|
+
// "valid": [
|
107
|
+
// {"bank_code":"68351976","account_number":"1116232594","converted_bank_code":"68351557","converted_account_number":"3047232594"}
|
108
|
+
// ]
|
109
|
+
// },
|
110
110
|
{
|
111
111
|
"convertor": "001001",
|
112
112
|
"valid": [
|
@@ -162,9 +162,15 @@
|
|
162
162
|
]
|
163
163
|
},
|
164
164
|
{
|
165
|
-
"convertor": "
|
165
|
+
"convertor": "004901",
|
166
166
|
"valid": [
|
167
|
-
{ "bank_code": "
|
167
|
+
{ "bank_code": "30060010", "account_number": "12345678", "converted_account_number": "12345678" }
|
168
168
|
]
|
169
169
|
}
|
170
|
+
// {
|
171
|
+
// "convertor": "001900",
|
172
|
+
// "valid": [
|
173
|
+
// { "bank_code": "50130100", "account_number": "556", "converted_bank_code": "50120383" }
|
174
|
+
// ]
|
175
|
+
// }
|
170
176
|
]
|
@@ -136,12 +136,12 @@
|
|
136
136
|
{ "bank_code": "10010010", "account_number" : "556", "converted_account_number": "0120440110" }
|
137
137
|
]
|
138
138
|
},
|
139
|
-
{
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
},
|
139
|
+
// {
|
140
|
+
// "convertor": "001900",
|
141
|
+
// "valid": [
|
142
|
+
// { "bank_code": "10010010", "account_number" : "1234567890", "converted_bank_code": "50120383" }
|
143
|
+
// ]
|
144
|
+
// },
|
145
145
|
{
|
146
146
|
"convertor": "002002",
|
147
147
|
"valid": [
|
@@ -318,6 +318,20 @@
|
|
318
318
|
{ "bank_code": "10010010", "account_number" : "0040400000" },
|
319
319
|
{ "bank_code": "10010010", "account_number" : "0040412000" }
|
320
320
|
]
|
321
|
+
},
|
322
|
+
{
|
323
|
+
"convertor": "004201",
|
324
|
+
"valid": [
|
325
|
+
{ "bank_code": "10010010", "account_number" : "0050462000" },
|
326
|
+
{ "bank_code": "70020001", "account_number" : "0040402000" },
|
327
|
+
{ "bank_code": "70020001", "account_number" : "1004400001" }
|
328
|
+
],
|
329
|
+
"invalid": [
|
330
|
+
{ "bank_code": "10010010", "account_number" : "504620001" },
|
331
|
+
{ "bank_code": "10010010", "account_number" : "0040400000" },
|
332
|
+
{ "bank_code": "10010010", "account_number" : "0040412000" },
|
333
|
+
{ "bank_code": "70020001", "account_number" : "1035400001" }
|
334
|
+
]
|
321
335
|
},
|
322
336
|
{
|
323
337
|
"convertor": "004301",
|
@@ -421,5 +435,16 @@
|
|
421
435
|
"valid": [
|
422
436
|
{ "bank_code": "10010010", "account_number" : "1234567890", "converted_bank_code": "66010200" }
|
423
437
|
]
|
438
|
+
},
|
439
|
+
{
|
440
|
+
"convertor": "004901",
|
441
|
+
"valid": [
|
442
|
+
{
|
443
|
+
"bank_code": "30060010",
|
444
|
+
"account_number": "1234567890",
|
445
|
+
"converted_bank_code": "30060010",
|
446
|
+
"converted_account_number": "1234567890"
|
447
|
+
}
|
448
|
+
]
|
424
449
|
}
|
425
450
|
]
|
data/spec/ibandit/iban_spec.rb
CHANGED
@@ -112,6 +112,22 @@ describe Ibandit::IBAN do
|
|
112
112
|
its(:local_check_digits) { is_expected.to be_nil }
|
113
113
|
end
|
114
114
|
|
115
|
+
context "when the IBAN was created from a Belgian IBAN" do
|
116
|
+
let(:iban_code) { "BE62510007547061" }
|
117
|
+
|
118
|
+
its(:country_code) { is_expected.to eq("BE") }
|
119
|
+
its(:bank_code) { is_expected.to eq("510") }
|
120
|
+
its(:branch_code) { is_expected.to be_nil }
|
121
|
+
its(:account_number) { is_expected.to eq("510007547061") }
|
122
|
+
its(:account_number_suffix) { is_expected.to be_nil }
|
123
|
+
its(:swift_bank_code) { is_expected.to eq("510") }
|
124
|
+
its(:swift_branch_code) { is_expected.to be_nil }
|
125
|
+
its(:swift_account_number) { is_expected.to eq("510007547061") }
|
126
|
+
its(:swift_national_id) { is_expected.to eq("510") }
|
127
|
+
its(:local_check_digits) { is_expected.to eq("61") }
|
128
|
+
its(:bban) { is_expected.to eq("510007547061") }
|
129
|
+
end
|
130
|
+
|
115
131
|
context "when the IBAN was created with local details" do
|
116
132
|
let(:arg) do
|
117
133
|
{
|
@@ -452,6 +468,13 @@ describe Ibandit::IBAN do
|
|
452
468
|
its(:to_s) { is_expected.to eq("") }
|
453
469
|
end
|
454
470
|
|
471
|
+
context "and account number has invalid characters in" do
|
472
|
+
let(:account_number) { "123456XX789" }
|
473
|
+
let(:bank_code) { "0036" }
|
474
|
+
|
475
|
+
its(:valid?) { is_expected.to be false }
|
476
|
+
end
|
477
|
+
|
455
478
|
context "and a 12 digit account number" do
|
456
479
|
let(:account_number) { "012345678900" }
|
457
480
|
let(:bank_code) { "0036" }
|
@@ -2247,16 +2270,16 @@ describe Ibandit::IBAN do
|
|
2247
2270
|
|
2248
2271
|
context "with an invalid branch code" do
|
2249
2272
|
let(:iban_code) { "GB60BARC20000055779911" }
|
2273
|
+
let(:valid_bank_code) { true }
|
2274
|
+
let(:valid_branch_code) { false }
|
2275
|
+
let(:valid_account_number) { true }
|
2276
|
+
|
2250
2277
|
before { Ibandit.bic_finder = double(call: "BARCGB22XXX") }
|
2251
2278
|
|
2252
2279
|
after { Ibandit.bic_finder = nil }
|
2253
2280
|
|
2254
2281
|
before { iban.valid_local_modulus_check? }
|
2255
2282
|
|
2256
|
-
let(:valid_bank_code) { true }
|
2257
|
-
let(:valid_branch_code) { false }
|
2258
|
-
let(:valid_account_number) { true }
|
2259
|
-
|
2260
2283
|
it "calls valid_branch_code? with an IBAN object" do
|
2261
2284
|
expect(Ibandit.modulus_checker).
|
2262
2285
|
to receive(:valid_branch_code?).
|
@@ -167,6 +167,12 @@ describe Ibandit::LocalDetailsCleaner do
|
|
167
167
|
its([:country_code]) { is_expected.to eq(country_code) }
|
168
168
|
its([:bank_code]) { is_expected.to eq("0036") }
|
169
169
|
its([:branch_code]) { is_expected.to eq("00063") }
|
170
|
+
|
171
|
+
context "with a hyphen" do
|
172
|
+
let(:account_number) { "0123456-789" }
|
173
|
+
|
174
|
+
its([:account_number]) { is_expected.to eq("000123456789") }
|
175
|
+
end
|
170
176
|
end
|
171
177
|
|
172
178
|
context "Cyprus" do
|
@@ -286,7 +292,7 @@ describe Ibandit::LocalDetailsCleaner do
|
|
286
292
|
|
287
293
|
context "with unsupported account details" do
|
288
294
|
let(:account_number) { "7955791111" }
|
289
|
-
let(:bank_code) { "
|
295
|
+
let(:bank_code) { "99999999" }
|
290
296
|
|
291
297
|
it { is_expected.to eq(local_details_with_swift) }
|
292
298
|
end
|
@@ -3,7 +3,7 @@
|
|
3
3
|
require "spec_helper"
|
4
4
|
|
5
5
|
describe Ibandit::PseudoIBANAssembler do
|
6
|
-
subject(:pseudo_iban) { described_class.new(local_details).assemble }
|
6
|
+
subject(:pseudo_iban) { described_class.new(**local_details).assemble }
|
7
7
|
|
8
8
|
context "for Sweden" do
|
9
9
|
context "with valid parameters" do
|
@@ -9,7 +9,7 @@ describe "structures.yml" do
|
|
9
9
|
structures.each do |country, rules|
|
10
10
|
context country do
|
11
11
|
rules.each do |rule, value|
|
12
|
-
next unless rule
|
12
|
+
next unless rule.to_s.end_with?("_format")
|
13
13
|
|
14
14
|
it "builds #{rule} rule" do
|
15
15
|
expect { Regexp.new(value) }.to_not raise_exception
|