Module: BrazilianUtils::NfeKeyUtils

Defined in:
lib/brazilian-utils/nfe-key-utils.rb

Overview

Note:

For NFCom and NF3e (models 62 and 66) the numeric code (cNF) field is 7 digits rather than 8, which shifts the rest of the key; no test case exercised these two models, so NfeKeyUtils.get_info always uses the general 8-digit layout. Its code/model fields for a 62/66 key should be treated as unverified.

Utilities for the 44-digit DF-e (Documento Fiscal eletrônico) access key shared by NF-e, NFC-e, CT-e, MDF-e, CT-e OS, GTV-e, BP-e, NF3e and NFCom.

Constant Summary collapse

LENGTH =
44
ID_PREFIXES =
%w[NFCom NF3e NFe CTe MDFe BPe].freeze
VALID_MODELS =
%w[55 65 57 58 67 64 63 66 62].freeze

Class Method Summary collapse

Class Method Details

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

Formats a DF-e access key into groups of 4 digits separated by spaces. Does not validate (use is_valid).

Parameters:

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

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

Returns:

  • (String)


53
54
55
56
57
58
59
60
# File 'lib/brazilian-utils/nfe-key-utils.rb', line 53

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

  apply_mask(digits, 4)
end

.get_info(value) ⇒ Hash?

Parses a DF-e access key into its fields.

Parameters:

  • value (String)

Returns:

  • (Hash, nil) —

    nil whenever is_valid would return false.



138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
# File 'lib/brazilian-utils/nfe-key-utils.rb', line 138

def self.get_info(value)
  return nil unless is_valid(value)

  digits = normalize(value)
  state = StateUtils.get_by_ibge_code(digits[0, 2])

  {
    stateCode: state[:code],
    year: 2000 + digits[2, 2].to_i,
    month: digits[4, 2].to_i,
    taxId: digits[6, 14],
    model: digits[20, 2],
    series: digits[22, 3].to_i,
    number: digits[25, 9].to_i,
    emissionType: digits[34, 1].to_i,
    code: digits[35, 8],
    checkDigit: digits[43, 1].to_i
  }
end

.is_valid(value) ⇒ Boolean Also known as: valid?

Validates a 44-digit DF-e access key.

Parameters:

  • value (String)

Returns:

  • (Boolean)


110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
# File 'lib/brazilian-utils/nfe-key-utils.rb', line 110

def self.is_valid(value)
  digits = normalize(value)
  return false unless digits

  cuf = digits[0, 2]
  model = digits[20, 2]
  nnf = digits[25, 9]
  tpemis = digits[34, 1]
  cnf = digits[35, 8]
  cdv = digits[43, 1]

  return false unless StateUtils.get_by_ibge_code(cuf)
  return false unless VALID_MODELS.include?(model)
  return false unless tpemis.match?(/\A[1-9]\z/)
  return false if nnf.to_i.zero?
  return false if %w[55 65].include?(model) && !cnf_ok?(cnf, nnf)

  cdv.to_i == check_digit(digits[0, 43])
end

.parse(value) ⇒ String

Removes the formatting of a DF-e access key and keeps only digits, capped to 44 digits. The XML Id prefixes are stripped first.

Parameters:

  • value (String, Integer)

Returns:

  • (String)


40
41
42
43
44
45
# File 'lib/brazilian-utils/nfe-key-utils.rb', line 40

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

  raw = strip_id_prefix(value.to_s)
  raw.gsub(/\D/, '')[0, LENGTH]
end