diff --git a/app/templates/cliente_form.html b/app/templates/cliente_form.html index 6985489..aa4ac73 100644 --- a/app/templates/cliente_form.html +++ b/app/templates/cliente_form.html @@ -51,7 +51,7 @@ {% endfor %}
* campos obrigatórios. Os demais podem ficar em branco — implantação/mensalidade/juros ficam 0,00 e as datas de contrato ficam com a data de hoje até serem ajustadas.
- + @@ -65,6 +65,113 @@ var $status = document.getElementById('cnpj-status'); if (!$cnpj) return; + var $botaoSalvar = document.getElementById('botao-salvar'); + + // Mesma fórmula de dígito verificador de app/normalize.py + // (_digito_verificador + validar_dv_cnpj) — módulo 11 sobre valor ASCII + // − 48 de cada caractere, suporta CNPJ numérico e o alfanumérico + // vigente desde 31/07/2026. + var PESOS_CNPJ_DV1 = [5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2]; + var PESOS_CNPJ_DV2 = [6, 5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2]; + + function digitoVerificador(valores, pesos) { + var soma = 0; + for (var i = 0; i < valores.length; i++) soma += valores[i] * pesos[i]; + var resto = soma % 11; + return resto < 2 ? 0 : 11 - resto; + } + + function valorCaractere(c) { + return c.charCodeAt(0) - 48; + } + + function validarDvCnpj(cnpj14) { + var base = []; + for (var i = 0; i < 12; i++) base.push(valorCaractere(cnpj14[i])); + var dvInformado = [parseInt(cnpj14[12], 10), parseInt(cnpj14[13], 10)]; + var dv1 = digitoVerificador(base, PESOS_CNPJ_DV1); + var dv2 = digitoVerificador(base.concat([dv1]), PESOS_CNPJ_DV2); + return dvInformado[0] === dv1 && dvInformado[1] === dv2; + } + + function detectarEValidarDocumento() { + var limpo = normalizarCnpj($cnpj.value); + if ($botaoSalvar) $botaoSalvar.disabled = false; + + if (/^[0-9]{11}$/.test(limpo)) { + if ($status) { + $status.textContent = 'CPF detectado.'; + $status.style.color = 'var(--cor-texto-secundario)'; + } + return; + } + if (/^[0-9A-Z]{12}[0-9]{2}$/.test(limpo)) { + if (validarDvCnpj(limpo)) { + if ($status) { + $status.textContent = 'CNPJ detectado.'; + $status.style.color = 'var(--cor-texto-secundario)'; + } + } else { + if ($status) { + $status.textContent = 'CNPJ inválido (dígito verificador não confere).'; + $status.style.color = 'var(--cor-perigo)'; + } + if ($botaoSalvar) $botaoSalvar.disabled = true; + } + return; + } + // Tamanho ainda incompleto/indeterminado: não bloqueia, não rotula. + if ($status) $status.textContent = ''; + } + + $cnpj.addEventListener('input', detectarEValidarDocumento); + + function aplicarMascaraTelefone(elemento, digitosAposDdd) { + elemento.addEventListener('input', function () { + var digitos = elemento.value.replace(/\D/g, ''); + // Se veio com DDI 55 colado (12-13 dígitos totais), usa só o resto. + var totalComDdi = 2 + digitosAposDdd; // DDI(2) + DDD(2) já contado em digitosAposDdd + if (digitos.length >= totalComDdi && digitos.slice(0, 2) === '55') { + digitos = digitos.slice(2); + } + digitos = digitos.slice(0, digitosAposDdd); + + var ddd = digitos.slice(0, 2); + var resto = digitos.slice(2); + var meio = resto.slice(0, digitosAposDdd - 6); + var fim = resto.slice(digitosAposDdd - 6); + + var formatado = ''; + if (ddd) formatado += '(' + ddd; + if (ddd.length === 2) formatado += ') '; + formatado += meio; + if (fim) formatado += '-' + fim; + elemento.value = formatado; + }); + } + + var $telefone = document.getElementById('TELEFONE'); + var $celular = document.getElementById('CELULAR'); + // TELEFONE: DDD(2) + 8 dígitos = 10 dígitos após o DDI. + if ($telefone) aplicarMascaraTelefone($telefone, 10); + // CELULAR: DDD(2) + 9 dígitos (com o 9 na frente) = 11 dígitos após o DDI. + if ($celular) aplicarMascaraTelefone($celular, 11); + + var $uf = document.getElementById('UF'); + if ($uf) { + $uf.addEventListener('input', function () { + $uf.value = $uf.value.toUpperCase().replace(/[^A-Z]/g, '').slice(0, 2); + }); + } + + var $cep = document.getElementById('CEP'); + if ($cep) { + $cep.addEventListener('input', function () { + var digitos = $cep.value.replace(/\D/g, '').slice(0, 8); + $cep.value = digitos.length > 5 ? digitos.slice(0, 5) + '-' + digitos.slice(5) : digitos; + }); + } + var CAMPOS_PARA_PREENCHER = ['RAZAO', 'FANTASIA', 'ENDERECO', 'CIDADE', 'BAIRRO', 'UF', 'CEP', 'TELEFONE', 'EMAIL']; function normalizarCnpj(valor) {