Skip to content

Instantly share code, notes, and snippets.

@mberlanda
Created July 27, 2016 12:49
Show Gist options
  • Save mberlanda/ccaf80ac8800a4188a0b6fe9b14524de to your computer and use it in GitHub Desktop.
Save mberlanda/ccaf80ac8800a4188a0b6fe9b14524de to your computer and use it in GitHub Desktop.
Partita IVA (Italian VAT identification number) checksum calculation and validation in Ruby
# https://it.wikipedia.org/wiki/Partita_IVA#Struttura_della_partita_IVA
module ChecksumCalculation
def calculate(ary)
(10 - t(ary)) % 10
end
private
def t(ary)
odd, even = separate_odd_even(ary)
(x(odd) + y(even)) % 10
end
def x(odd)
odd.inject(0){ |sum, x| sum += x }
end
def y(even)
even.inject(0){ |sum, x| sum += process_even(x)}
end
def separate_odd_even(ary)
hash = Hash[*ary]
return hash.keys, hash.values
end
def process_even(n)
n*2 > 9 ? n*2 - 9 : n*2
end
end
module ChecksumValidation
def validate(ary)
(10 - t(ary)) % 10
end
private
def t(ary)
odd, even = separate_odd_even(ary)
(x(odd) + y(even)+ z(even)) % 10
end
def x(odd)
odd.inject(0){ |sum, x| sum += x }
end
def y(even)
even.inject(0){ |sum, x| sum += x*2}
end
def z(even)
even.count{|x| x >= 5}
end
def separate_odd_even(ary)
hash = Hash[*ary]
return hash.keys, hash.values
end
end
class VatNumber
extend ChecksumValidation
class << self
def is_valid?(vat_number)
return false if !check_length(vat_number)
validate_checksum(vat_number)
end
def check_length(vat_number)
vat_number.size == 11
end
def validate_checksum(vat_number)
ary = vat_number.split('').map(&:to_i)
check_value = ary.pop
validate(ary) == check_value
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment