require "national-ids-validator/version" require "yaml" require "national-ids-validator/validator" #if defined? ActiveModel class NationalIdsValidator SUPPORTED_COUNTRY_CODES = %w(PL NO) def self.specifications @@rules ||= YAML.load_file(File.expand_path("national-ids-validator/rules.yml", File.dirname(__FILE__))) end def initialize(value,country_code) @country_code = country_code.to_s.strip.gsub(/\s+/, '').upcase @value = value.to_s.strip.gsub(/\s+/, '').upcase unless self.class::SUPPORTED_COUNTRY_CODES.include?(@country_code) raise RuntimeError.new("Unexpected country code '#{country_code}' that is not yet supported") end end def self.valid?(value,code) new(value,code).valid? end def valid? valid_length? && valid_check_digits? end def valid_length? !!specification && specification['length'] == @value.length end def valid_check_digits? status = false v = self.number_data # binding.pry case @country_code when "NO" #http://no.wikipedia.org/wiki/F%C3%B8dselsnummer #first control digit weights1 = specification['weights1'] first_sum = 0 0.upto(@value.length - 3).each do |i| first_sum += @value[i].to_i*weights1[i].to_i end first_digit = 11 - (first_sum % 11) #second control digit weights2 = specification['weights2'] second_sum = 0 0.upto(@value.length - 2).each do |i| second_sum += @value[i].to_i*weights2[i].to_i end second_digit = 11 - (second_sum % 11) #check digits calculated = [first_digit, second_digit].map!{|k| k == 11 ? 0 : k} control = [v["control"][0].to_i, v["control"][1].to_i] if calculated[0] == control[0] && calculated[1] == control[1] status = true end # binding.pry when "PL" weights = specification['weights'] sum = 0 0.upto(@value.length - 2).each do |i| sum += @value[i].to_i*weights[i].to_i end first_digit = 10 - (sum % 10) calculated = first_digit == 10 ? 0 : first_digit control = v["control"][0].to_i if calculated == control status = true end end return status end def number_data @number_data ||= Regexp.new("^#{specification['regexp']}$").match(@value) if specification end def gender #0 - man, 1 - woman if self.valid? case @country_code when "NO" number_data['individual'][2] % 2 == 0 ? 1 : 0 when "PL" number_data['individual'][3] % 2 == 0 ? 1 : 0 end end end private def specification @specification ||= self.class.specifications[@country_code.downcase] end # def method_missing(method_name, *args) # respond_to?(method_name) ? number_data[method_name] : super # end # # def respond_to_missing?(method_name, include_private=false) # (number_data && number_data.names.include?(method_name.to_s)) || super # end end