Pessoal, segue Classe para validar CNPJ alfanumérico Receita Federal, que entra em vigor a partir de julho de 2026.
link: CNPJ Alfanumérico — Receita Federal
{ /// <summary>
/// Valida um CPF, CNPJ numérico ou CNPJ alfanumérico.
/// Detecta o tipo (11 ou 14 dígitos) e chama o validador apropriado.
/// Retorna 1 (true) se válido, 0 (false) se inválido.
/// </summary>
/// <param name="documento">O número do CPF ou CNPJ, com ou sem formatação.</param>
ClassMethod Validar(documento As %String) As %Boolean
{
// 1. Limpa a formatação (pontos, traços, barras) e converte para MAIÚSCULO
Set docLimpo = ..LimparFormatacao(documento)
Set len = $LENGTH(docLimpo)
// 2. Direciona para o método correto baseado no tamanho
If len = 11 {
Quit ..ValidarCPF(docLimpo)
}
If len = 14 {
Quit ..ValidarCNPJ(docLimpo)
}
// Se não tiver 11 ou 14 dígitos, é inválido
Quit 0
} /// <summary>
/// Valida um número de CPF (11 dígitos).
/// </summary>
/// <param name="cpf">O CPF (idealmente já sem formatação).</param>
ClassMethod ValidarCPF(cpf As %String) As %Boolean [ Private ]
{
Set cpf = ..LimparFormatacao(cpf) // Garante limpeza extra
If $LENGTH(cpf) '= 11 { Quit 0 }
// CORREÇÃO: Verifica se todos os dígitos são iguais (ex: "11111111111")
If $TRANSLATE(cpf, $EXTRACT(cpf, 1), "") = "" { Quit 0 }
// Cálculo DV1
Set soma = 0
For i = 1:1:9 {
Set soma = soma + ($EXTRACT(cpf, i) * (11 - i))
}
Set resto = soma # 11
Set dv1 = $SELECT(resto < 2: 0, 1: 11 - resto)
If dv1 '= $EXTRACT(cpf, 10) { Quit 0 }
// Cálculo DV2
Set soma = 0
For i = 1:1:10 {
Set soma = soma + ($EXTRACT(cpf, i) * (12 - i))
}
Set resto = soma # 11
Set dv2 = $SELECT(resto < 2: 0, 1: 11 - resto)
If dv2 '= $EXTRACT(cpf, 11) { Quit 0 }
Quit 1
} /// <summary>
/// Valida um número de CNPJ (14 posições), numérico ou alfanumérico,
/// conforme o Anexo XV da IN RFB nº 2.119/2022 (adicionado pela IN RFB nº 2229/2024).
/// </summary>
/// <param name="cnpj">O CNPJ (já limpo e em maiúsculas).</param>
ClassMethod ValidarCNPJ(cnpj As %String) As %Boolean [ Private ]
{
If $LENGTH(cnpj) '= 14 {
Quit 0
} // CORREÇÃO: Verifica sequências de caracteres idênticos (ex: "AAAA...")
If $TRANSLATE(cnpj, $EXTRACT(cnpj, 1), "") = "" {
Quit 0
}
// 3. Cálculo do 1º Dígito Verificador (DV1)
Set soma = 0
Set pesos = "543298765432"
For i = 1:1:12 {
Set char = $EXTRACT(cnpj, i)
Set valor = $ASCII(char) - 48
Set soma = soma + (valor * $EXTRACT(pesos, i))
}
Set resto = soma # 11
Set dv1 = $SELECT(resto < 2: 0, 1: 11 - resto)
// 4. Verifica o DV1
If dv1 '= $EXTRACT(cnpj, 13) { Quit 0 }
// 5. Cálculo do 2º Dígito Verificador (DV2)
Set soma = 0
Set pesos = "6543298765432"
For i = 1:1:13 {
Set char = $EXTRACT(cnpj, i)
Set valor = $ASCII(char) - 48
Set soma = soma + (valor * $EXTRACT(pesos, i))
}
Set resto = soma # 11
Set dv2 = $SELECT(resto < 2: 0, 1: 11 - resto)
// 6. Verifica o DV2
If dv2 '= $EXTRACT(cnpj, 14) { Quit 0 }
// Se passou por tudo, é válido
Quit 1
} /// <summary>
/// Remove caracteres de formatação (., -, /) e converte para MAIÚSCULAS.
/// </summary>
ClassMethod LimparFormatacao(valor As %String) As %String [ Private ]
{
Set valorLimpo = $TRANSLATE(valor, ".-/", "")
Quit $ZCONVERT(valorLimpo, "U")
} }
// Testando um CNPJ numérico antigo (ainda válido)
USER> WRITE ##class(Utils.BR.Validador).Validar("33.000.167/0001-01")
USER>1
// Testando um CPF (não mudou)
USER> WRITE ##class(Utils.BR.Validador).Validar("123.456.789-00")
USER>1
// NOVO TESTE: O CNPJ Alfanumérico do Exemplo 2 da RFB [cite: 44]
USER> WRITE ##class(Utils.BR.Validador).Validar("12.ABC.345/01DE-35")
USER>1
// NOVO TESTE: O mesmo CNPJ com dígito verificador errado
USER> WRITE ##class(Utils.BR.Validador).Validar("12.ABC.345/01DE-30")
USER>0
// NOVO TESTE: Com letras minúsculas (será tratado)
USER> WRITE ##class(Utils.BR.Validador).Validar("12.abc.345/01de-35")
USER>1
Se houver necessidade de ajuste, fiquem a vontade para informar.
Obrigado.

