From 3384df24b7aa6ec17940355a2bb2c1b8e27c00a7 Mon Sep 17 00:00:00 2001 From: Laural Date: Sun, 4 Jul 2021 18:49:46 -0500 Subject: [PATCH] Fix spanish organisation number --- lib/faker/default/company.rb | 2 +- test/faker/default/test_faker_company.rb | 39 ++++++++++++++++++++++-- 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/lib/faker/default/company.rb b/lib/faker/default/company.rb index e80c79afd1..14d83584f2 100644 --- a/lib/faker/default/company.rb +++ b/lib/faker/default/company.rb @@ -553,7 +553,7 @@ def inn_checksum(factor, number) end def spanish_cif_control_digit(organization_type, code) - letters = %w[J A B C D E F G H] + letters = %w[J A B C D E F G H I] control = code.split('').each_with_index.inject(0) do |sum, (value, index)| if (index + 1).even? diff --git a/test/faker/default/test_faker_company.rb b/test/faker/default/test_faker_company.rb index e0442942a8..0d4581b1fd 100644 --- a/test/faker/default/test_faker_company.rb +++ b/test/faker/default/test_faker_company.rb @@ -28,8 +28,8 @@ def test_type end def test_spanish_organisation_number - cif = @tester.spanish_organisation_number(organization_type: 'A') - assert @tester.send(:spanish_cif_control_digit, 'A', cif[1..7]) == cif[-1].to_i + assert cif_valid?(@tester.spanish_organisation_number(organization_type: 'A')) + assert cif_valid?(@tester.spanish_organisation_number) end def test_swedish_organisation_number @@ -269,4 +269,39 @@ def inn_checksum(number) v + i[0] * number[i[1]].to_i end % 11 % 10 end + + def cif_valid?(cif) + letters_cif = %w[A B C D E F G H J N P Q R S U V W] + letter_cif_number = %w[P Q S W] + letters_cif_control = %w[J A B C D E F G H I] + regex_cif = /^(#{letters_cif.join('|')})-?(\d{7})-?(\d|#{letters_cif_control.join('|')})$/ + + if cif =~ regex_cif + number = Regexp.last_match(2) + first_letter = Regexp.last_match(1) + province_code = number[0..1] + actual_control = Regexp.last_match(3) + + total = number.split('').each_with_index.inject(0) do |acc, (element, index)| + acc + if index.even? + (element.to_i * 2).digits.inject(:+) + else + element.to_i + end + end + + decimal = total.digits.first + expected_control = decimal != 0 ? 10 - decimal : decimal + + # Control code must be a letter + return letters_cif_control[expected_control] if letter_cif_number.include?(first_letter) || + province_code == '00' + + # Control code will be a number or a letter + return [expected_control.to_s, + letters_cif_control[expected_control]].include?(actual_control) + end + + false + end end