lib/cfita/codice_fiscale.rb in cfita-0.0.5 vs lib/cfita/codice_fiscale.rb in cfita-0.0.6
- old
+ new
@@ -1,9 +1,9 @@
# frozen_string_literal: true
require 'active_support/all'
-require 'cfita/codici_catastali'
+require 'cfita/codici_catastali.rb'
module Cfita
# Controllo codice fiscale italiano
class CodiceFiscale
attr_reader :fiscal_code,
@@ -14,27 +14,32 @@
def self.ccat
@ccat ||= JSON.parse(open('ccat.json'))
end
- def initialize(fiscal_code, birth_place: nil, birth_date: nil)
+ def initialize(
+ fiscal_code,
+ birth_place: nil,
+ birth_date: nil,
+ name: nil,
+ surname: nil
+ )
@fiscal_code = fiscal_code.upcase.strip
@birth_place = birth_place&.upcase
@birth_date = birth_date && (birth_date.is_a?(Date) ? birth_date : Date.parse(birth_date))
- @data = {}
+ @name = name&.parameterize&.upcase
+ @surname = surname&.parameterize&.upcase
@errors = []
parse
end
def to_s
fiscal_code
end
- def valid?(birth_place: nil)
- result = errors.empty?
- result = birth_place?(birth_place) if result && birth_place
- result
+ def valid?
+ errors.empty?
end
private
def parse
@@ -43,14 +48,52 @@
return if errors.any?
check_checksum
return if errors.any?
+ check_name
+ check_surname
check_birth_date
check_birth_place
end
+ def check_name
+ return unless @name
+
+ a, b, c, d = consonants(@name)
+ name_code = (
+ (d ? [a, c, d] : [a, b, c]).compact.join +
+ vowels(@name).join +
+ 'XXX'
+ )[0..2]
+
+ errors << "Il nome non corrisponde al codice '#{name_code}'" unless name_code == @fiscal_code[3..5]
+ end
+
+ def check_surname
+ return unless @surname
+
+ surname_code = (
+ consonants(@surname).join +
+ vowels(@surname).join +
+ 'XXX'
+ )[0..2]
+
+ errors << "Il cognome non corrisponde al codice '#{surname_code}'" unless surname_code == @fiscal_code[0..2]
+ end
+
+ VOWELS = 'AEIOU'.chars.freeze
+ CONSONANTS = (('A'..'Z').to_a - VOWELS).freeze
+
+ def vowels(word)
+ word.chars.select { |char| char.in? VOWELS }
+ end
+
+ def consonants(word)
+ word.chars.select { |char| char.in? CONSONANTS }
+ end
+
def check_size
size = @fiscal_code.size
errors << "Lunghezza errata (#{size})" unless size == 16
end
@@ -99,11 +142,11 @@
@errors << "Luogo di nascita #{@birth_place} non coerente, al codice catastale #{codice_catastale} corrisponde a #{birth_places.join(' o a ')}"
end
end
end
- MESI = 'ABCDEHLMPRST'.freeze
+ MESI = 'ABCDEHLMPRST'
def check_birth_date
yy = cifre(6..7)
return if @errors.any?
@@ -127,12 +170,12 @@
else
@birth_date = date
end
end
- def yy2yyyy(yy)
+ def yy2yyyy(year_as_yy)
Date.today.year -
- (Date.today.year % 100 + 100 - yy ) % 100
+ (Date.today.year % 100 + 100 - year_as_yy) % 100
end
def cifre(range)
result = 0
range.each do |position|