Module: BrazilianUtils::CertidaoUtils

Defined in:
lib/brazilian-utils/certidao-utils.rb

Overview

Utilities for the matrícula of a certidão de registro civil (art. 473 of the Código Nacional de Normas da Corregedoria Nacional de Justiça): a 32-digit number grouped as 6-2-2-4-1-5-3-7-2 (registry CNS, acervo, serviço, ano, tipo do livro, livro, folha, termo, 2 check digits).

Constant Summary collapse

BOOK_TYPES =

Maps the single-digit "tipo do livro" code to its name.

{
  '1' => 'birth',
  '2' => 'marriage',
  '3' => 'religiousMarriage',
  '4' => 'death',
  '5' => 'stillbirth',
  '6' => 'banns',
  '7' => 'other',
  '8' => 'emancipation',
  '9' => 'interdiction'
}.freeze
FIELD_SIZES =
[6, 2, 2, 4, 1, 5, 3, 7, 2].freeze
FIELD_KEYS =
%i[registryCns acervo service year type book page term checkDigits].freeze

Class Method Summary collapse

Class Method Details

.format(value, options = {}) ⇒ String

Formats a matrícula into the printed groups (6-2-2-4-1-5-3-7-2), separated by spaces, applied as far as the digits go.

Parameters:

  • value (String, Integer)
  • options (Hash) (defaults to: {}) —

    :pad left-pads with zeros to 32 digits first.

Returns:

  • (String)


44
45
46
47
48
49
50
# File 'lib/brazilian-utils/certidao-utils.rb', line 44

def self.format(value, options = {})
  digits = value.to_s.gsub(/\D/, '')
  digits = digits.rjust(32, '0') if options[:pad] || options['pad']
  return '' if digits.empty?

  apply_mask(digits, FIELD_SIZES, [' '] * 8)
end

.get_info(value, options = {}) ⇒ Hash?

Parses a certidão matrícula into its fields.

Parameters:

  • value (String, Integer) —

    Same accepted forms as is_valid.

  • options (Hash) (defaults to: {}) —

    Same as is_valid.

Returns:

  • (Hash, nil) —

    nil whenever is_valid would return false; otherwise a Hash with :registryCns, :acervo, :service, :year (Integer), :type (the book-type name), :book, :page, :term and :checkDigits.



152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
# File 'lib/brazilian-utils/certidao-utils.rb', line 152

def self.get_info(value, options = {})
  return nil unless is_valid(value, options)

  digits = clean_for_validation(value)
  raw = extract_fields(digits)

  {
    registryCns: raw[:registryCns],
    acervo: raw[:acervo],
    service: raw[:service],
    year: raw[:year].to_i,
    type: BOOK_TYPES[raw[:type]],
    book: raw[:book],
    page: raw[:page],
    term: raw[:term],
    checkDigits: raw[:checkDigits]
  }
end

.is_valid(value, options = {}) ⇒ Boolean Also known as: valid?

Checks whether a certidão matrícula is structurally valid and its 2 modulus-11 check digits match.

Parameters:

  • value (String, Integer) —

    The matrícula, bare or separated by any mix of space, ., - or /. Any other character (a letter, for instance) anywhere in the value makes it invalid.

  • options (Hash) (defaults to: {}) —

    :accept an optional Array narrowing which book-type codes (as the raw digit string, e.g. "1") or names (e.g. "birth") are accepted; defaults to accepting all of 1-9.

Returns:

  • (Boolean)


118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# File 'lib/brazilian-utils/certidao-utils.rb', line 118

def self.is_valid(value, options = {})
  digits = clean_for_validation(value)
  return false unless digits
  return false unless digits.match?(/\A\d{32}\z/)

  raw = extract_fields(digits)
  return false unless raw[:service] == '55'
  return false unless BOOK_TYPES.key?(raw[:type])

  accept = options[:accept] || options['accept']
  if accept
    accepted = Array(accept).map(&:to_s)
    return false unless accepted.include?(raw[:type]) || accepted.include?(BOOK_TYPES[raw[:type]])
  end

  base30 = digits[0, 30]
  dv1 = check_digit(base30)
  dv2 = check_digit(base30 + dv1.to_s)

  raw[:checkDigits] == "#{dv1}#{dv2}"
end

.parse(value) ⇒ String

Removes the formatting of a certidão matrícula and keeps only digits, capped to 32 digits.

Parameters:

  • value (String, Integer)

Returns:

  • (String)


57
58
59
60
61
# File 'lib/brazilian-utils/certidao-utils.rb', line 57

def self.parse(value)
  return '' unless value.is_a?(String) || value.is_a?(Integer)

  value.to_s.gsub(/\D/, '')[0, 32]
end