lib/rfc_facil/homoclave_calculator.rb
module RfcFacil
class HomoclaveCalculator
HOMOCLAVE_DIGITS = '123456789ABCDEFGHIJKLMNPQRSTUVWXYZ'.freeze
FULL_NAME_MAPPING = {
' ' => '00', '0' => '00', '1' => '01', '2' => '02', '3' => '03', '4' => '04',
'5' => '05', '6' => '06', '7' => '07', '8' => '08', '9' => '09', '&' => '10',
'A' => '11', 'B' => '12', 'C' => '13', 'D' => '14', 'E' => '15', 'F' => '16',
'G' => '17', 'H' => '18', 'I' => '19', 'J' => '21', 'K' => '22', 'L' => '23',
'M' => '24', 'N' => '25', 'O' => '26', 'P' => '27', 'Q' => '28', 'R' => '29',
'S' => '32', 'T' => '33', 'U' => '34', 'V' => '35', 'W' => '36', 'X' => '37',
'Y' => '38', 'Z' => '39', 'Ñ' => '40'
}.freeze
attr_accessor :person, :full_name, :mapped_full_name, :pairs_of_digits_sum, :homoclave
def initialize(person)
@person = person
end
def calculate
normalize_full_name
map_full_name_to_digits_code
sum_pairs_of_digits
build_homoclave
@homoclave
end
private
def build_homoclave
last_three_digits = (@pairs_of_digits_sum % 1000)
quo = (last_three_digits / 34)
reminder = (last_three_digits % 34)
@homoclave = "#{HOMOCLAVE_DIGITS[quo]}#{HOMOCLAVE_DIGITS[reminder]}"
end
def sum_pairs_of_digits
@pairs_of_digits_sum = 0
(0..@mapped_full_name.length - 2).each do |i|
num1 = @mapped_full_name[i..i + 1].to_i
num2 = @mapped_full_name[i + 1..i + 1].to_i
@pairs_of_digits_sum += num1 * num2
end
end
def map_full_name_to_digits_code
@mapped_full_name = '0'
@full_name.each_char do |c|
@mapped_full_name << map_character_to_two_digit_code(c)
end
end
def map_character_to_two_digit_code(c)
return FULL_NAME_MAPPING[c] if FULL_NAME_MAPPING.key?(c)
raise ArgumentError, "No two-digit-code mapping for char: #{c}"
end
def normalize_full_name
raw_full_name = UnicodeUtils.upcase(@person.to_s)
@full_name = I18n.transliterate(raw_full_name)
@full_name.gsub!(/[-.']/, '') # remove .'-
add_missing_char_to_full_name(raw_full_name, 'Ñ')
end
def add_missing_char_to_full_name(raw_full_name, missing_char)
index = raw_full_name.index(missing_char)
until index.nil?
@full_name[index] = missing_char
index = raw_full_name.index(missing_char, index + 1)
end
end
end
end