class ItalianPersonalTaxCodeValidator

Thanks to github.com/freego/italian_job

Constants

BUSINESS_REGEX
DISPARI
REGEX

Public Instance Methods

validate_each(record, attribute, value) click to toggle source
# File lib/active_model/validations/italian_personal_tax_code_validator.rb, line 12
def validate_each(record, attribute, value)
  return if options[:allow_blank] && value.blank?
  return if allow_vat_numbers?(record) && value.match(BUSINESS_REGEX)

  record.errors.add(attribute, :invalid) unless control_code_valid?(value)
end

Private Instance Methods

allow_vat_numbers?(record) click to toggle source
# File lib/active_model/validations/italian_personal_tax_code_validator.rb, line 21
def allow_vat_numbers?(record)
  return true if options[:allow_vat_numbers] == true
  return true if options[:allow_vat_numbers].respond_to?(:call) && options[:allow_vat_numbers].call(record)

  false
end
control_code_valid?(value) click to toggle source
# File lib/active_model/validations/italian_personal_tax_code_validator.rb, line 28
def control_code_valid?(value) # rubocop:disable Metrics/AbcSize
  return false unless value.match(REGEX)

  odds = []
  evens = []
  value[0..14].split('').each_with_index { |e, i| (i + 1).odd? ? odds << e : evens << e }
  odd = odds.inject(0) { |sum, current_char| sum + DISPARI[(current_char.ord < 65 ? current_char.to_i : ((current_char.ord - 54) - 1))] }
  even = evens.inject(0) { |sum, current_char| sum + (current_char.ord < 65 ? current_char.to_i : current_char.ord - 65) }
  (((odd + even) % 26) + 65).chr == value[15].chr
end