Module: Nfcom::Utils::Helpers

Class Method Summary collapse

Class Method Details

.apenas_numeros(texto) ⇒ Object

Remove caracteres não numéricos



40
41
42
# File 'lib/nfcom/utils/helpers.rb', line 40

def apenas_numeros(texto)
  texto.to_s.gsub(/\D/, '')
end

.cnpj_valido?(cnpj) ⇒ Boolean

Valida CNPJ

Parameters:

  • cnpj (String)

    CNPJ com ou sem formatação

Returns:

  • (Boolean)

    true se válido, false caso contrário



96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/nfcom/utils/helpers.rb', line 96

def cnpj_valido?(cnpj) # rubocop:disable Metrics/AbcSize
  return false if cnpj.nil?

  cnpj_limpo = apenas_numeros(cnpj)
  return false if cnpj_limpo.length != 14
  return false if cnpj_limpo.chars.uniq.length == 1 # Todos dígitos iguais

  calc_digito = lambda do |numeros|
    multiplicadores = [6, 5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2]
    soma = numeros.chars.each_with_index.sum { |d, i| d.to_i * multiplicadores[i + (13 - numeros.length)] }
    resto = soma % 11
    resto < 2 ? 0 : 11 - resto
  end

  base = cnpj_limpo[0..11]
  digito1 = calc_digito.call(base)
  digito2 = calc_digito.call(base + digito1.to_s)

  cnpj_limpo[-2].to_i == digito1 && cnpj_limpo[-1].to_i == digito2
end

.cpf_valido?(cpf) ⇒ Boolean

Valida CPF

Parameters:

  • cpf (String)

    CPF com ou sem formatação

Returns:

  • (Boolean)

    true se válido, false caso contrário



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

def cpf_valido?(cpf) # rubocop:disable Metrics/AbcSize
  return false if cpf.nil?

  cpf_limpo = apenas_numeros(cpf)
  return false if cpf_limpo.length != 11
  return false if cpf_limpo.chars.uniq.length == 1 # Todos dígitos iguais

  calc_digito = lambda do |numeros, peso_inicial|
    soma = numeros.chars.each_with_index.sum { |d, i| d.to_i * (peso_inicial - i) }
    resto = soma % 11
    resto < 2 ? 0 : 11 - resto
  end

  base = cpf_limpo[0..8]
  digito1 = calc_digito.call(base, 10)
  digito2 = calc_digito.call(base + digito1.to_s, 11)

  cpf_limpo[-2].to_i == digito1 && cpf_limpo[-1].to_i == digito2
end

.formatar_cep(cep) ⇒ Object

Formata CEP



81
82
83
84
85
86
# File 'lib/nfcom/utils/helpers.rb', line 81

def formatar_cep(cep)
  numeros = apenas_numeros(cep)
  return cep if numeros.length != 8

  "#{numeros[0..4]}-#{numeros[5..7]}"
end

.formatar_cnpj(cnpj) ⇒ Object

Formata CNPJ



65
66
67
68
69
70
# File 'lib/nfcom/utils/helpers.rb', line 65

def formatar_cnpj(cnpj)
  numeros = apenas_numeros(cnpj)
  return cnpj if numeros.length != 14

  "#{numeros[0..1]}.#{numeros[2..4]}.#{numeros[5..7]}/#{numeros[8..11]}-#{numeros[12..13]}"
end

.formatar_cpf(cpf) ⇒ Object

Formata CPF



73
74
75
76
77
78
# File 'lib/nfcom/utils/helpers.rb', line 73

def formatar_cpf(cpf)
  numeros = apenas_numeros(cpf)
  return cpf if numeros.length != 11

  "#{numeros[0..2]}.#{numeros[3..5]}.#{numeros[6..8]}-#{numeros[9..10]}"
end

.formatar_data(date) ⇒ Object

Formata data para padrão AAAA-MM-DD



32
33
34
35
36
37
# File 'lib/nfcom/utils/helpers.rb', line 32

def formatar_data(date)
  date = safe_to_date(date)
  return nil unless date

  date.strftime('%Y-%m-%d')
end

.formatar_data_hora(datetime) ⇒ Object

Formata data/hora para padrão ISO 8601



27
28
29
# File 'lib/nfcom/utils/helpers.rb', line 27

def formatar_data_hora(datetime)
  datetime.strftime('%Y-%m-%dT%H:%M:%S%:z')
end

.formatar_decimal(valor, casas = 2) ⇒ Object

Formata valor decimal para uso no XML (2 casas decimais)



9
10
11
# File 'lib/nfcom/utils/helpers.rb', line 9

def formatar_decimal(valor, casas = 2)
  format("%.#{casas}f", valor.to_f)
end

.gerar_id(prefixo = 'ID') ⇒ Object

Gera ID único para elementos XML



89
90
91
# File 'lib/nfcom/utils/helpers.rb', line 89

def gerar_id(prefixo = 'ID')
  "#{prefixo}#{Time.now.to_i}#{SecureRandom.hex(4)}"
end

.limitar_texto(texto, tamanho_max) ⇒ Object

Limita texto ao tamanho máximo



45
46
47
48
49
# File 'lib/nfcom/utils/helpers.rb', line 45

def limitar_texto(texto, tamanho_max)
  texto = texto.to_s.strip
  texto = texto[0...tamanho_max].strip if texto.length > tamanho_max
  texto
end

.remover_acentos(texto) ⇒ Object

Remove acentos e caracteres especiais



52
53
54
55
56
57
# File 'lib/nfcom/utils/helpers.rb', line 52

def remover_acentos(texto)
  texto.to_s
    .unicode_normalize(:nfkd)
    .encode('ASCII', invalid: :replace, undef: :replace, replace: '')
    .gsub(/[^\w\s-]/, '')
end

.safe_to_date(value) ⇒ Date?

Converte String ou Date para Date de forma segura (sem depender do Rails)

Parameters:

  • value (String, Date, Time, DateTime, nil)

Returns:

  • (Date, nil)


16
17
18
19
20
21
22
23
24
# File 'lib/nfcom/utils/helpers.rb', line 16

def safe_to_date(value)
  return nil if value.nil?
  return value if value.is_a?(Date)
  return value.to_date if value.respond_to?(:to_date) && !value.is_a?(String)

  Date.parse(value.to_s)
rescue ArgumentError
  nil
end

.vazio?(texto) ⇒ Boolean

Valida se uma string está vazia

Returns:

  • (Boolean)


60
61
62
# File 'lib/nfcom/utils/helpers.rb', line 60

def vazio?(texto)
  texto.to_s.strip.empty?
end