ibandit 1.13.0 → 1.15.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 78a7fd2e1ca3e1062a4200e0d07f961c67783b1f93f69ed348143ee066d2d8f3
4
- data.tar.gz: 0736d59cf783918276ba8fb1376325e58bd37cdbc306c0b05ae583df89aaaf18
3
+ metadata.gz: 15eee0ef8f82ced114c7aedc52a70c88ab69877928356200917723e0416af1a8
4
+ data.tar.gz: a1d8b2feda3f775c0c25f481f58194e5e9dab9af2e8d8406007697e96564d178
5
5
  SHA512:
6
- metadata.gz: f5d478dd806b967e1903abdf20eff7fcca90128ca7e1949deb760ea55aedad4dfc862bf45ff89b11566e5155b0ec9e60fea61bf966e431ac6718ec54d3965aef
7
- data.tar.gz: dcdd42b6b06eea11236d27f7c0bdd9da9cf45f9a2502e5f8bb9e0903351965127645b8c50874871c5ed737bf60389ec0542b2778e9e2cb20c11c746d30a4f593
6
+ metadata.gz: a728382a2bb8e522ca8cb547938052f9fdf84dc1d81388e07f6465705c81ea61ad1b0a1cfd84deac1cc5a9f6d873ca98c9f510d1526f07ffff48fa9e746c08fa
7
+ data.tar.gz: 3a5d6917918b1744b9c4dd86651f6099acea270a4b1029b2f7cbc18b25bdd832271b9780e35c8141bcc8273736859698bb1b0893a3688833d4690e3480486c8e
data/.rubocop.yml CHANGED
@@ -4,7 +4,7 @@ inherit_gem:
4
4
  require: rubocop-rails
5
5
 
6
6
  AllCops:
7
- TargetRubyVersion: 2.5
7
+ TargetRubyVersion: 3.2
8
8
 
9
9
  # Limit lines to 90 characters.
10
10
  Layout/LineLength:
data/CHANGELOG.md CHANGED
@@ -1,3 +1,12 @@
1
+ ## 1.15.0 - March 28, 2023
2
+
3
+ - Improve the error messages that are generated
4
+
5
+ ## 1.14.0 - March 28, 2023
6
+
7
+ - Update IBAN registry #233
8
+ - Add GL and FO to the IBAN constructor for local details
9
+
1
10
  ## 1.13.0 - March 6, 2023
2
11
 
3
12
  - Update BLZ data - BLZ_20230306
@@ -1,6 +1,8 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
3
 
4
+ # rubocop:disable Layout/LineLength
5
+
4
6
  # Script for parsing the IBAN registry (IBAN_Registry.txt) and IBAN structures
5
7
  # (IBANSTRUCTURE.xml) files from SWIFT.
6
8
  require "csv"
@@ -22,143 +24,240 @@ end
22
24
 
23
25
  class Report
24
26
  include SAXMachine
25
- elements "ibanstructure", as: :countries, class: Country
27
+ elements "ibanstructure_v2", as: :countries, class: Country
26
28
  end
27
29
 
28
- # rubocop:disable Metrics/AbcSize
29
- def get_iban_structures(iban_structures_file, iban_registry_file)
30
- bban_formats = get_bban_formats(iban_registry_file)
31
-
32
- report = Report.parse(iban_structures_file)
33
- report.countries.each_with_object({}) do |country, hash|
34
- hash[country.country_code] = {
35
- bank_code_position: country.bank_code_position.to_i,
36
- bank_code_length: country.bank_code_length.to_i,
37
- branch_code_position: country.branch_code_position.to_i,
38
- branch_code_length: country.branch_code_length.to_i,
39
- account_number_position: country.account_number_position.to_i,
40
- account_number_length: country.account_number_length.to_i,
41
- total_length: country.total_length.to_i,
42
- national_id_length: country.national_id_length.to_i,
43
- }.merge(bban_formats[country.country_code])
30
+ class IbanRegistryTextFile
31
+ attr_accessor :lines, :registry
32
+
33
+ FILE_ELEMENTS = [
34
+ # 0 Data element
35
+ # 1 Name of country
36
+ # 2 IBAN prefix country code (ISO 3166)
37
+ COUNTRY_CODE = 2,
38
+ # 3 Country code includes other countries/territories
39
+ # 4 SEPA country
40
+ # 5 SEPA country also includes
41
+ # 6 Domestic account number example
42
+ DOMESTIC_ACCOUNT_NUMBER_EXAMPLE = 6,
43
+ # 7 BBAN
44
+ # 8 BBAN structure
45
+ BBAN_STRUCTURE = 8,
46
+ # 9 BBAN length
47
+ # 10 Bank identifier position within the BBAN
48
+ BANK_IDENTIFIER_POSITION = 10,
49
+ # 11 Bank identifier pattern
50
+ BANK_IDENTIFIER_PATTERN = 11,
51
+ # 12 Branch identifier position within the BBAN
52
+ BRANCH_IDENTIFIER_POSITION = 12,
53
+ # 13 Branch identifier pattern
54
+ BRANCH_IDENTIFIER_PATTERN = 13,
55
+ # 14 Bank identifier example
56
+ # 15 Branch identifier example
57
+ # 16 BBAN example
58
+ BBAN_EXAMPLE = 16,
59
+ # 17 IBAN
60
+ # 18 IBAN structure
61
+ # 19 IBAN length
62
+ # 20 Effective date
63
+ # 21 IBAN electronic format example
64
+ IBAN_EXAMPLE = 21,
65
+ ].freeze
66
+
67
+ def self.call(path = "../data/raw/IBAN_Registry.txt")
68
+ lines = CSV.read(
69
+ File.expand_path(path, __dir__),
70
+ col_sep: "\t",
71
+ headers: true,
72
+ encoding: Encoding::ISO_8859_1,
73
+ ).to_a.transpose.tap(&:shift)
74
+
75
+ new(lines).tap(&:parse)
44
76
  end
45
- end
46
- # rubocop:enable Metrics/AbcSize
47
-
48
- FILE_ELEMENTS = [
49
- # 0 Data element
50
- # 1 Name of country
51
- # 2 IBAN prefix country code (ISO 3166)
52
- COUNTRY_CODE = 2,
53
- # 3 Country code includes other countries/territories
54
- # 4 SEPA country
55
- # 5 SEPA country also includes
56
- # 6 Domestic account number example
57
- # 7 BBAN
58
- # 8 BBAN structure
59
- BBAN_STRUCTURE = 8,
60
- # 9 BBAN length
61
- # 10 Bank identifier position within the BBAN
62
- # 11 Bank identifier pattern
63
- BANK_IDENTIFIER_PATTERN = 11,
64
- # 12 Branch identifier position within the BBAN
65
- # 13 Branch identifier pattern
66
- BRANCH_IDENTIFIER_PATTERN = 13,
67
- # 14 Bank identifier example
68
- # 15 Branch identifier example
69
- # 16 BBAN example
70
- # 17 IBAN
71
- # 18 IBAN structure
72
- # 19 IBAN length
73
- # 20 Effective date
74
- # 21 IBAN electronic format example
75
- ].freeze
76
-
77
- def get_bban_formats(iban_registry_file)
78
- iban_registry_file.each_with_object({}) do |line, hash|
79
- bban_structure = line[BBAN_STRUCTURE].strip
80
-
81
- bank_code_structure = line[BANK_IDENTIFIER_PATTERN].strip
82
- branch_code_structure = line[BRANCH_IDENTIFIER_PATTERN]&.strip
83
-
84
- bank_code_structure = "" if bank_code_structure == "N/A"
85
-
86
- country_code = line[COUNTRY_CODE].strip
87
- hash[country_code] = convert_swift_convention(bban_structure,
88
- bank_code_structure,
89
- branch_code_structure)
77
+
78
+ def initialize(lines)
79
+ @lines = lines
80
+ @registry = {}
90
81
  end
91
- end
92
82
 
93
- # IBAN Registry has BBAN format (which seems to be accurate), and Bank
94
- # identifier length, which contains something roughly like the format for the
95
- # bank code and usually the branch code where applicable. This is a best attempt
96
- # to convert those from weird SWIFT-talk into regexes, and then work out the
97
- # account number format regex by taking the bank and branch code regexes off
98
- # the front of the BBAN format.
99
- #
100
- # This works about 70% of the time, the rest are overridden in
101
- # structure_additions.yml
102
- def convert_swift_convention(bban, bank, branch)
103
- bban_regex = iban_registry_to_regex(bban)
104
- bank_regex = iban_registry_to_regex(bank)
105
- branch_regex = branch.nil? ? nil : iban_registry_to_regex(branch)
106
-
107
- non_account_number_regex = [bank_regex, branch_regex].join
108
- account_number_start = (bban_regex.index(non_account_number_regex) || 0) +
109
- non_account_number_regex.length
110
- account_number_regex = bban_regex[account_number_start..-1]
111
-
112
- {
113
- bban_format: bban_regex,
114
- bank_code_format: bank_regex,
115
- branch_code_format: branch_regex,
116
- account_number_format: account_number_regex,
117
- }.compact
83
+ def parse
84
+ lines.each do |line|
85
+ country_code = clean_string(line[COUNTRY_CODE])
86
+
87
+ bban_details = convert_swift_convention(
88
+ country_code: country_code,
89
+ bban_structure: clean_string(line[BBAN_STRUCTURE]),
90
+ bank_code_structure: clean_string(line[BANK_IDENTIFIER_PATTERN]),
91
+ branch_code_structure: clean_string(line[BRANCH_IDENTIFIER_PATTERN]),
92
+ bank_identifier_position: clean_string(line[BANK_IDENTIFIER_POSITION]),
93
+ branch_identifier_position: clean_string(line[BRANCH_IDENTIFIER_POSITION]),
94
+ ) || {}
95
+
96
+ registry[country_code] = {
97
+ iban_example: clean_string(line[IBAN_EXAMPLE]),
98
+ bban_example: clean_string(line[BBAN_EXAMPLE]),
99
+ domestic_account_number_example: clean_string(line[DOMESTIC_ACCOUNT_NUMBER_EXAMPLE]),
100
+ **bban_details,
101
+ }.compact
102
+ end
103
+ end
104
+
105
+ private
106
+
107
+ def clean_string(string)
108
+ return nil if string.nil?
109
+
110
+ string.strip!
111
+ return nil if string == "N/A"
112
+
113
+ string
114
+ end
115
+
116
+ # IBAN Registry has BBAN format (which seems to be accurate), and Bank
117
+ # identifier length, which contains something roughly like the format for the
118
+ # bank code and usually the branch code where applicable. This is a best attempt
119
+ # to convert those from weird SWIFT-talk into regexes, and then work out the
120
+ # account number format regex by taking the bank and branch code regexes off
121
+ # the front of the BBAN format.
122
+ #
123
+ # This works about 90% of the time, the rest are overridden in
124
+ # structure_additions.yml
125
+ def convert_swift_convention( # rubocop:todo Metrics/AbcSize
126
+ country_code:,
127
+ bban_structure:,
128
+ branch_code_structure:,
129
+ bank_code_structure: nil,
130
+ bank_identifier_position: nil,
131
+ branch_identifier_position: nil
132
+ )
133
+ bban_regex = iban_registry_to_regex(bban_structure)
134
+ bank_regex = iban_registry_to_regex(bank_code_structure)
135
+ branch_regex = branch_code_structure.nil? ? nil : iban_registry_to_regex(branch_code_structure)
136
+
137
+ bban_ranges = create_bban_ranges(bban_structure)
138
+ ranges_to_remove = [
139
+ convert_string_range(bank_identifier_position),
140
+ convert_string_range(branch_identifier_position),
141
+ ].compact.uniq
142
+ max_bank_details_index = ranges_to_remove.map(&:last).max
143
+
144
+ _, non_bank_identifier_ranges = bban_ranges.partition do |_, range|
145
+ max_bank_details_index >= range.last
146
+ end
147
+
148
+ account_number_regex = iban_registry_to_regex(non_bank_identifier_ranges.map(&:first).join)
149
+
150
+ {
151
+ bban_format: bban_regex.source,
152
+ bank_code_format: bank_regex.source,
153
+ branch_code_format: branch_regex&.source,
154
+ account_number_format: account_number_regex.source,
155
+ }
156
+ rescue StandardError => e
157
+ puts "-----------------"
158
+ puts "Issue with: #{country_code}"
159
+ puts "\t #{e.message}"
160
+ puts "\t #{e.backtrace}"
161
+ puts "\t -----------------"
162
+ puts "\t country_code: #{country_code}"
163
+ puts "\t bban_structure: #{bban_structure}"
164
+ puts "\t branch_code_structure: #{branch_code_structure}"
165
+ puts "\t bank_code_structure: #{bank_code_structure}"
166
+ puts "\t bank_identifier_position: #{bank_identifier_position}"
167
+ puts "\t branch_identifier_position: #{branch_identifier_position}"
168
+ end
169
+
170
+ # Given "4!n4!n12!c" this returns an array that contains the ranges that cover the
171
+ # structure. Eg; [["4!n", 0..3]]
172
+ def create_bban_ranges(bban_structure)
173
+ arr = bban_structure.scan(/((\d+)![anc])/)
174
+
175
+ start = 0
176
+
177
+ arr.each_with_object([]) do |(structure, length), acc|
178
+ end_number = start + length.to_i - 1
179
+ acc.push([structure, start..end_number])
180
+ start = end_number + 1
181
+ end
182
+ end
183
+
184
+ def convert_string_range(str)
185
+ start_val, end_val = str.split("-").map(&:to_i)
186
+ (start_val - 1)..(end_val - 1)
187
+ rescue StandardError
188
+ nil
189
+ end
190
+
191
+ def iban_registry_to_regex(swift_string)
192
+ regex = swift_string.
193
+ gsub(/(\d+)!n/, '\\d{\1}').
194
+ gsub(/(\d+)!a/, '[A-Z]{\1}').
195
+ gsub(/(\d+)!c/, '[A-Z0-9]{\1}')
196
+ Regexp.new(regex)
197
+ end
118
198
  end
119
199
 
120
- def iban_registry_to_regex(swift_string)
121
- swift_string.gsub(/(\d+)!([nac])/, '\2{\1}').
122
- gsub("n", '\d').
123
- gsub("a", "[A-Z]").
124
- gsub("c", "[A-Z0-9]")
200
+ class IbanStructureFile
201
+ attr_accessor :report, :iban_registry_file
202
+
203
+ def self.call(iban_registry_file, path: "../data/raw/IBANSTRUCTURE.xml")
204
+ iban_structures_file = File.read(File.expand_path(path, __dir__))
205
+ new(iban_registry_file:, iban_structures_file:).parse
206
+ end
207
+
208
+ def initialize(iban_registry_file:, iban_structures_file:)
209
+ @iban_registry_file = iban_registry_file
210
+ @report = Report.parse(iban_structures_file)
211
+ end
212
+
213
+ def parse # rubocop:todo Metrics/AbcSize
214
+ report.countries.each_with_object({}) do |country, hash|
215
+ country_bban = iban_registry_file.registry[country.country_code] || {}
216
+
217
+ hash[country.country_code] = {
218
+ bank_code_position: country.bank_code_position.to_i,
219
+ bank_code_length: country.bank_code_length.to_i,
220
+ branch_code_position: country.branch_code_position.to_i,
221
+ branch_code_length: country.branch_code_length.to_i,
222
+ account_number_position: country.account_number_position.to_i,
223
+ account_number_length: country.account_number_length.to_i,
224
+ total_length: country.total_length.to_i,
225
+ national_id_length: country.national_id_length.to_i,
226
+ **country_bban,
227
+ }
228
+ end
229
+ end
125
230
  end
126
231
 
127
232
  def merge_structures(structures, additions)
128
233
  additions.each_pair do |key, value|
129
- structures[key].merge!(value) if structures.include?(key)
234
+ structures[key].merge!(value).compact! if structures.include?(key)
130
235
  end
131
236
 
132
237
  structures
133
238
  end
134
239
 
240
+ def load_yaml_file(path)
241
+ YAML.safe_load(
242
+ File.read(File.expand_path(path, __dir__)),
243
+ permitted_classes: [Range, Symbol, Regexp],
244
+ )
245
+ end
246
+
135
247
  # Only parse the files if this file is run as an executable (not required in,
136
248
  # as it is in the specs)
137
249
  if __FILE__ == $PROGRAM_NAME
138
- iban_registry_file = CSV.read(
139
- File.expand_path("../data/raw/IBAN_Registry.txt", __dir__),
140
- col_sep: "\t",
141
- headers: true,
142
- encoding: Encoding::ISO_8859_1,
143
- ).to_a.transpose
144
-
145
- iban_registry_file.shift
146
-
147
- iban_structures_file = File.read(
148
- File.expand_path("../data/raw/IBANSTRUCTURE.xml", __dir__),
149
- )
250
+ old_file = load_yaml_file("../data/structures.yml")
150
251
 
151
- iban_structures = get_iban_structures(
152
- iban_structures_file,
153
- iban_registry_file,
154
- )
252
+ iban_registry_file = IbanRegistryTextFile.call
253
+ iban_structures = IbanStructureFile.call(iban_registry_file)
155
254
 
156
- structure_additions = YAML.safe_load(
157
- File.read(File.expand_path("../data/raw/structure_additions.yml", __dir__)),
158
- permitted_classes: [Range, Symbol],
159
- )
255
+ structure_additions = load_yaml_file("../data/raw/structure_additions.yml")
160
256
 
161
257
  complete_structures = merge_structures(iban_structures, structure_additions)
258
+ pseudo_ibans = load_yaml_file("../data/raw/pseudo_ibans.yml")
259
+
260
+ complete_structures.merge!(pseudo_ibans)
162
261
 
163
262
  output_file_path = File.expand_path(
164
263
  "../data/structures.yml",
@@ -166,4 +265,12 @@ if __FILE__ == $PROGRAM_NAME
166
265
  )
167
266
 
168
267
  File.open(output_file_path, "w") { |f| f.write(complete_structures.to_yaml) }
268
+
269
+ new_countries = old_file.keys.to_set ^ complete_structures.keys.to_set
270
+ puts "New countries:"
271
+ new_countries.each do |country|
272
+ puts "#{country} #{complete_structures[country][:iban_example]} #{complete_structures[country][:domestic_account_number_example]}"
273
+ end
169
274
  end
275
+
276
+ # rubocop:enable Layout/LineLength
@@ -10,3 +10,10 @@ da:
10
10
  invalid_format: "Uventet format for en IBAN fra %{country_code}."
11
11
  is_invalid: "er ugyldig"
12
12
  does_not_support_payments: "understøtter ikke betalinger"
13
+ has_invalid_format: "ugyldigt format"
14
+ failed_checksum_test: "bestod ikke kontrolsumtesten"
15
+ failed_modulus_check: "bestod ikke moduluskontrollen"
16
+ has_invalid_length: "ugyldig længde"
17
+ bank_code_does_not_exist: "bankkoden findes ikke"
18
+ has_invalid_clearing_code_length: "længden på clearingskoden er ugyldig"
19
+ has_invalid_serial_number: "ugyldigt serienummer"
@@ -10,3 +10,10 @@ de:
10
10
  invalid_format: "Unerwartetes Format für eine %{country_code}-IBAN."
11
11
  is_invalid: "ist ungültig"
12
12
  does_not_support_payments: "unterstützt keine Zahlungen"
13
+ has_invalid_format: "Format ist ungültig"
14
+ failed_checksum_test: "Prüfsummentest nicht bestanden"
15
+ failed_modulus_check: "Modulprüfung nicht bestanden"
16
+ has_invalid_length: "Länge ist ungültig"
17
+ bank_code_does_not_exist: "Bankleitzahl existiert nicht"
18
+ has_invalid_clearing_code_length: "Länge des Verrechnungscodes ist ungültig"
19
+ has_invalid_serial_number: "Seriennummer ist ungültig"
@@ -10,3 +10,10 @@ en:
10
10
  invalid_format: "Unexpected format for a %{country_code} IBAN."
11
11
  is_invalid: "is invalid"
12
12
  does_not_support_payments: "does not support payments"
13
+ has_invalid_format: "format is invalid"
14
+ failed_checksum_test: "did not pass checksum test"
15
+ failed_modulus_check: "did not pass modulus check"
16
+ has_invalid_length: "length is invalid"
17
+ bank_code_does_not_exist: "bank code does not exist"
18
+ has_invalid_clearing_code_length: "clearing code length is invalid"
19
+ has_invalid_serial_number: "serial number is invalid"
@@ -10,3 +10,10 @@ es:
10
10
  invalid_format: "Formato inesperado para un IBAN de %{country_code}."
11
11
  is_invalid: "no es válido"
12
12
  does_not_support_payments: "no admite pagos"
13
+ has_invalid_format: "formato invalido"
14
+ failed_checksum_test: "fallo en suma de control"
15
+ failed_modulus_check: "fallo en control de modulo"
16
+ has_invalid_length: "tamaño invalido"
17
+ bank_code_does_not_exist: "codigo bancario inexistente"
18
+ has_invalid_clearing_code_length: "codigo de oficina de oficina de compensación invalido"
19
+ has_invalid_serial_number: "número de serie invalido"
@@ -10,3 +10,10 @@ fr:
10
10
  invalid_format: "Format non attendu pour un IBAN %{country_code}."
11
11
  is_invalid: "n'est pas valide"
12
12
  does_not_support_payments: "ne prend pas en charge les paiements"
13
+ has_invalid_format: "le format n'est pas valide"
14
+ failed_checksum_test: "échec du test de la somme de contrôle"
15
+ failed_modulus_check: "échec du test de module"
16
+ has_invalid_length: "la longueur n'est pas valide"
17
+ bank_code_does_not_exist: "le code de la banque n'existe pas"
18
+ has_invalid_clearing_code_length: "la longueur du clearing code n'est pas valide"
19
+ has_invalid_serial_number: "le numéro de série n'est pas valide"
@@ -9,4 +9,12 @@ it:
9
9
  non_alphanumeric_characters: "Caratteri non alfanumerici trovati: %{characters}"
10
10
  invalid_format: "Formato imprevisto per un IBAN %{country_code}."
11
11
  is_invalid: "non è valido"
12
- does_not_support_payments: "non supporta i pagamenti"
12
+ does_not_support_payments: "non supporta i pagamenti"
13
+ has_invalid_format: "formato non valido"
14
+ failed_checksum_test: "test del checksum non superato"
15
+ failed_modulus_check: "test del modulo non superato"
16
+ has_invalid_length: "lunghezza non valida"
17
+ bank_code_does_not_exist: "codice banca inesistente"
18
+ has_invalid_clearing_code_length: "lunghezza clearing code non valida"
19
+ has_invalid_serial_number: "numero di serie non valido"
20
+
@@ -10,3 +10,10 @@ nb:
10
10
  invalid_format: "Uventet format for IBAN for %{country_code}."
11
11
  is_invalid: "er ikke gyldig"
12
12
  does_not_support_payments: "støtter ikke betalinger"
13
+ has_invalid_format: "formatet er ugyldig"
14
+ failed_checksum_test: "besto ikke kontrollsumtesten"
15
+ failed_modulus_check: "besto ikke tallverdikontrollen"
16
+ has_invalid_length: "ugyldig lengde"
17
+ bank_code_does_not_exist: "bankkoden eksisterer ikke"
18
+ has_invalid_clearing_code_length: "registreringsnummerets lengde er ugyldig"
19
+ has_invalid_serial_number: "ugyldig serienummer"
@@ -10,3 +10,10 @@ nl:
10
10
  invalid_format: "Onverwachte formaat voor een %{country_code} IBAN."
11
11
  is_invalid: "is ongeldig"
12
12
  does_not_support_payments: "ondersteunt geen betalingen"
13
+ has_invalid_format: "indeling is ongeldig"
14
+ failed_checksum_test: "checksumtest is mislukt"
15
+ failed_modulus_check: "moduluscontrole is mislukt"
16
+ has_invalid_length: "lengte is ongeldig"
17
+ bank_code_does_not_exist: "bankcode bestaat niet"
18
+ has_invalid_clearing_code_length: "lengte clearingcode is ongeldig"
19
+ has_invalid_serial_number: "serienummer is ongeldig"
@@ -10,3 +10,10 @@ pt:
10
10
  invalid_format: "Formato inesperado para um IBAN %{country_code}."
11
11
  is_invalid: "é inválido"
12
12
  does_not_support_payments: "não suporta pagamentos"
13
+ has_invalid_format: "o formato é inválido"
14
+ failed_checksum_test: "não passou no teste de verificação de soma"
15
+ failed_modulus_check: "não passou na verificação do módulo"
16
+ has_invalid_length: "o comprimento é inválido"
17
+ bank_code_does_not_exist: "o código do banco não existe"
18
+ has_invalid_clearing_code_length: "o comprimento do código de libertação é inválido"
19
+ has_invalid_serial_number: "o número de série é inválido"
@@ -10,3 +10,10 @@ sl:
10
10
  invalid_format: "Nepričakovana oblika zapisa %{country_code} v IBAN."
11
11
  is_invalid: "ni veljavno"
12
12
  does_not_support_payments: "ne podpira plačil"
13
+ has_invalid_format: "oblika zapisa ni veljavna"
14
+ failed_checksum_test: "neuspešen preizkus kontrolne vsote"
15
+ failed_modulus_check: "neuspešno preverjanje modula"
16
+ has_invalid_length: "dolžina ni veljavna"
17
+ bank_code_does_not_exist: "koda banke ne obstaja"
18
+ has_invalid_clearing_code_length: "dolžina klirinške kode ni veljavna"
19
+ has_invalid_serial_number: "serijska številka ni veljavna"
@@ -10,3 +10,10 @@ sv:
10
10
  invalid_format: "Oväntat format för %{country_code} IBAN."
11
11
  is_invalid: "är ogiltig"
12
12
  does_not_support_payments: "stödjer inte betalningar"
13
+ has_invalid_format: "ogiltigt format"
14
+ failed_checksum_test: "felaktig kontrollsumma"
15
+ failed_modulus_check: "felaktig modulkontroll"
16
+ has_invalid_length: "ogiltig längd"
17
+ bank_code_does_not_exist: "bankkoden existerar inte"
18
+ has_invalid_clearing_code_length: "clearingnumrets längd är ogiltigt"
19
+ has_invalid_serial_number: "ogiltigt serienummer"