Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix spanish organisation number #2351

Merged
merged 1 commit into from Aug 8, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion lib/faker/default/company.rb
Expand Up @@ -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?
Expand Down
39 changes: 37 additions & 2 deletions test/faker/default/test_faker_company.rb
Expand Up @@ -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
Expand Down Expand Up @@ -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