Skip to content

Instantly share code, notes, and snippets.

@marviorocha
Last active October 26, 2020 12:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save marviorocha/3b50e02dd0f87a03e717bbc790c74b12 to your computer and use it in GitHub Desktop.
Save marviorocha/3b50e02dd0f87a03e717bbc790c74b12 to your computer and use it in GitHub Desktop.
Ruby On Rails Validator CNPJ
class CnpjValidator < ActiveModel::EachValidator
class InvalidCNPJ < StandardError; end
EXPECTED_FORMAT = /^\d{2}\.\d{3}\.\d{3}\/\d{4}\-\d{2}$/
FIRST_CHECKER_DIGITS_MULTIPLIERS = [5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2]
SECOND_CHECKER_DIGITS_MULTIPLIERS = [6, 5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2]
def validate_each(record, attribute, value)
return unless value.present?
@record, @attribute, @value = [record, attribute, value]
validates_data
rescue InvalidCNPJ => e
@record.errors[@attribute] << e.message
end
private
def validates_data
unless @value.match?(EXPECTED_FORMAT) && valid_digits?
raise InvalidCNPJ.new(options[:message] || "is not a valid CNPJ")
end
end
def valid_digits?
number, check = @value.gsub(/\.|\//, '').split('-')
first_checker_digit = discover_checker_digit(number, FIRST_CHECKER_DIGITS_MULTIPLIERS)
number += first_checker_digit.to_s
second_checker_digit = discover_checker_digit(number, SECOND_CHECKER_DIGITS_MULTIPLIERS)
check == "#{first_checker_digit}#{second_checker_digit}"
end
def discover_checker_digit(number, digits_multipliers)
multiplied_values = number.split('').map.with_index do |num, index|
num.to_i * digits_multipliers[index]
end
division = multiplied_values.sum % 11
division < 2 ? 0 : (11 - division)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment