Calculadora de Rescisão

Calculadora de Rescisão
:root{ –bg:#f8fafc; –card:#ffffff; –muted:#475569; –text:#1e293b; –accent:#16a34a; –danger:#dc2626; –border:#cbd5e1; } *{box-sizing:border-box} body{ margin:0; background:var(–bg); font-family:system-ui,-apple-system,Segoe UI,Roboto,Ubuntu,”Helvetica Neue”,Arial; color:var(–text); line-height:1.45; } .wrap{max-width:1100px;margin:24px auto;padding:16px} h1{font-size:clamp(22px,3.5vw,32px);margin:0 0 8px} p.hint{color:var(–muted);margin:4px 0 16px} .grid{display:grid;grid-template-columns:1fr;gap:14px} @media (min-width:900px){.grid{grid-template-columns:1.1fr 1fr}} .card{ background:var(–card); border:1px solid var(–border); border-radius:16px; padding:16px; box-shadow:0 4px 10px rgba(0,0,0,.05); } .card h2{font-size:18px;margin:0 0 10px} .row{display:grid;grid-template-columns:1fr;gap:10px;margin-bottom:10px} @media (min-width:640px){.row{grid-template-columns:repeat(2,minmax(0,1fr))}} label{display:flex;flex-direction:column;font-size:13px;color:var(–muted);gap:6px} input, select{ background:#f9fafb; border:1px solid var(–border); border-radius:10px; padding:10px 12px; color:var(–text); font-size:14px; outline:none; } input[type=”number”]::-webkit-outer-spin-button, input[type=”number”]::-webkit-inner-spin-button{appearance:none;margin:0} .inline{display:flex;gap:10px;flex-wrap:wrap;align-items:center} .btn{ cursor:pointer; border:1px solid var(–border); background:#f1f5f9; padding:10px 14px; border-radius:12px; font-weight:600; color:var(–text); transition:.15s; text-decoration:none; display:inline-block; } .btn:hover{transform:translateY(-1px);background:#e2e8f0} .btn.primary{background:var(–accent);color:#fff;border-color:#15803d} .btn.danger{background:var(–danger);color:#fff;border-color:#991b1b} .kpi{ display:flex; justify-content:space-between; align-items:center; padding:12px; border:1px dashed var(–border); border-radius:12px; margin:10px 0; background:#f8fafc; } .kpi b{font-size:18px} .muted{color:var(–muted);font-size:13px} table{width:100%;border-collapse:separate;border-spacing:0 8px} th,td{text-align:left;padding:10px 12px} th{font-size:12px;color:var(–muted)} tr{background:#f9fafb;border-radius:10px} tr td:first-child{border-top-left-radius:10px;border-bottom-left-radius:10px} tr td:last-child{border-top-right-radius:10px;border-bottom-right-radius:10px;text-align:right} .pos{color:#15803d} .neg{color:#dc2626} .tot{font-weight:800} .footer{font-size:12px;color:var(–muted);margin-top:10px} .badge{ font-size:12px; padding:3px 8px; border:1px solid var(–border); border-radius:999px; background:#f1f5f9; margin-left:6px; color:var(–muted); }

Preencha os campos abaixo.

Dados do Contrato

Dias trabalhados no mês da demissão
Tempo de casa (anos/meses)
Aviso prévio legal (dias)

Proporcionais & Ajustes

Resumo

VerbaValor (R$)
Total de Proventos
Total de Descontos
Total Líquido
(function(){ const el = id => document.getElementById(id); const salarioEl = el(‘salario’); const tipoEl = el(‘tipo’); const admissaoEl = el(‘admissao’); const demissaoEl = el(‘demissao’); const avisoEl = el(‘aviso’); const descontarAvisoEl = el(‘descontarAviso’); const meses13El = el(‘meses13’); const mesesFeriasEl = el(‘mesesFerias’); const feriasVencidasDiasEl = el(‘feriasVencidasDias’); const faltasDiasEl = el(‘faltasDias’); const fgtsSaldoEl = el(‘fgtsSaldo’); const adiantamentosEl = el(‘adiantamentos’); const diasMesEl = el(‘diasMes’); const tempoCasaEl = el(‘tempoCasa’); const avisoDiasEl = el(‘avisoDias’); const tabelaBody = document.querySelector(‘#tabela tbody’); const totProvEl = el(‘totProventos’); const totDescEl = el(‘totDescontos’); const totLiqEl = el(‘totLiquido’); const fmt = v => isFinite(v) ? v.toLocaleString(‘pt-BR’,{style:’currency’,currency:’BRL’}) : ‘—’; function parseNum(elm){ const v = (elm.value || ”).toString().replace(‘,’, ‘.’); return v === ” ? NaN : Number(v); } function diffYM(a, b){ const start = new Date(a.getFullYear(), a.getMonth(), a.getDate()); const end = new Date(b.getFullYear(), b.getMonth(), b.getDate()); let anos = end.getFullYear() – start.getFullYear(); let meses = end.getMonth() – start.getMonth(); let dias = end.getDate() – start.getDate(); if (dias < 0){ const prevMonth = new Date(end.getFullYear(), end.getMonth(), 0).getDate(); dias += prevMonth; meses -= 1; } if (meses < 0){ meses += 12; anos -= 1; } return {anos, meses, dias}; } function countMonthsRule15(startDate, endDate){ if (!startDate || !endDate || endDate < startDate) return 0; let count = 0; let cur = new Date(startDate.getFullYear(), startDate.getMonth(), 1); const end = new Date(endDate.getFullYear(), endDate.getMonth(), 1); while (cur = 15) count++; cur = new Date(year, month+1, 1); } return count; } function avisoPrevioLegalDias(adm, dem){ if (!adm || !dem || dem dem) inicio = new Date(dem.getFullYear()-1, adm.getMonth(), adm.getDate()); return countMonthsRule15(inicio, dem); } function multaFgtsPercent(tipo){ switch (tipo){ case ‘sem_justa’: return 40; case ‘acordo’: return 20; default: return 0; } } function renderLinha(nome, valor, classe=’pos’){ const tr = document.createElement(‘tr’); const td1 = document.createElement(‘td’); td1.textContent = nome; const td2 = document.createElement(‘td’); td2.className = classe; td2.textContent = fmt(valor); tr.appendChild(td1); tr.appendChild(td2); tabelaBody.appendChild(tr); } function calcular(){ tabelaBody.innerHTML = ”; let proventos = 0, descontos = 0; const salario = parseNum(salarioEl); const tipo = tipoEl.value; const adm = admissaoEl.value ? new Date(admissaoEl.value+’T12:00:00′) : null; const dem = demissaoEl.value ? new Date(demissaoEl.value+’T12:00:00′) : null; const aviso = avisoEl.value; const descontarAviso = descontarAvisoEl.value === ‘sim’; if (!salario || !dem){ renderLinha(‘Preencha salário e data de demissão’, 0, ‘neg’); totProvEl.textContent = ‘—’; totDescEl.textContent = ‘—’; totLiqEl.textContent = ‘—’; return; } const diasMes = diasTrabalhadosMes(dem); diasMesEl.textContent = diasMes || ‘—’; const tc = (adm && dem) ? diffYM(adm, dem) : {anos:0,meses:0}; tempoCasaEl.textContent = adm ? `${tc.anos}a ${tc.meses}m` : ‘—’; const avisoLegal = avisoPrevioLegalDias(adm, dem); avisoDiasEl.textContent = avisoLegal || ‘—’; const saldoSalario = (salario/30) * diasMes; if (saldoSalario>0){ proventos += saldoSalario; renderLinha(‘Saldo de salário’, saldoSalario); } let m13 = meses13El.value === ” ? calcAutoMeses13(adm, dem) : Number(meses13El.value); if (!isFinite(m13) || m1312) m13 = 12; const decimo = salario * (m13/12); if (decimo>0){ proventos += decimo; renderLinha(`13º proporcional (${m13} m)`, decimo); } let mFer = mesesFeriasEl.value === ” ? calcAutoMesesFerias(adm, dem) : Number(mesesFeriasEl.value); if (!isFinite(mFer) || mFer12) mFer = 12; const feriasProp = salario * (mFer/12); const tercoProp = feriasProp/3; if (feriasProp>0){ proventos += feriasProp + tercoProp; renderLinha(`Férias proporcionais (${mFer} m)`, feriasProp); renderLinha(`1/3 de férias proporcionais`, tercoProp); } const ferVencDias = Number(feriasVencidasDiasEl.value || 0); if (ferVencDias>0){ const ferVenc = (salario/30)*ferVencDias; const tercoVenc = ferVenc/3; proventos += ferVenc + tercoVenc; renderLinha(`Férias vencidas (${ferVencDias} dias)`, ferVenc); renderLinha(`1/3 de férias vencidas`, tercoVenc); } if (aviso === ‘indenizado’){ if (tipo === ‘sem_justa’ || tipo === ‘acordo’){ const baseDias = avisoLegal || 30; let avisoIndenizado = salario/30 * baseDias; if (tipo === ‘acordo’) avisoIndenizado *= 0.5; if (avisoIndenizado>0){ proventos += avisoIndenizado; renderLinha(`Aviso prévio indenizado`, avisoIndenizado); } } } if (tipo === ‘pedido’ && descontarAviso){ const descontoAviso = salario; descontos += descontoAviso; renderLinha(‘Desconto aviso não trabalhado (30 dias)’, -descontoAviso, ‘neg’); } const faltasDias = Number(faltasDiasEl.value || 0); if (faltasDias>0){ const descFaltas = (salario/30)*faltasDias; descontos += descFaltas; renderLinha(`Desconto por faltas/atrasos (${faltasDias} dias)`, -descFaltas, ‘neg’); } const adiant = parseNum(adiantamentosEl) || 0; if (adiant>0){ descontos += adiant; renderLinha(‘Adiantamentos/Descontos diversos’, -adiant, ‘neg’); } const fgtsSaldo = parseNum(fgtsSaldoEl) || 0; const fgtsPct = multaFgtsPercent(tipo); if (fgtsSaldo>0 && fgtsPct>0){ const multa = fgtsSaldo * (fgtsPct/100); proventos += multa; renderLinha(`Multa FGTS (${fgtsPct}% sobre saldo informado)`, multa); } totProvEl.textContent = fmt(proventos); totDescEl.textContent = fmt(descontos); totLiqEl.textContent = fmt(proventos – descontos); } function recalcAuto(){ const adm = admissaoEl.value ? new Date(admissaoEl.value+’T12:00:00′) : null; const dem = demissaoEl.value ? new Date(demissaoEl.value+’T12:00:00′) : null; meses13El.value = calcAutoMeses13(adm, dem) || ”; mesesFeriasEl.value = calcAutoMesesFerias(adm, dem) || ”; avisoDiasEl.textContent = avisoPrevioLegalDias(adm, dem) || ‘—’; diasMesEl.textContent = dem ? dem.getDate() : ‘—’; if (adm && dem){ const tc = diffYM(adm, dem); tempoCasaEl.textContent = `${tc.anos}a ${tc.meses}m`; } else { tempoCasaEl.textContent = ‘—’; } } el(‘calc’).addEventListener(‘click’, e => { e.preventDefault(); calcular(); }); el(‘auto’).addEventListener(‘click’, e => { e.preventDefault(); recalcAuto(); calcular(); }); el(‘limpar’).addEventListener(‘click’, e => { e.preventDefault(); document.querySelectorAll(‘input’).forEach(i=>i.value=”); tipoEl.value=’sem_justa’; avisoEl.value=’trabalhado’; descontarAvisoEl.value=’nao’; tabelaBody.innerHTML=”; totProvEl.textContent=’—’; totDescEl.textContent=’—’; totLiqEl.textContent=’—’; diasMesEl.textContent=’—’; tempoCasaEl.textContent=’—’; avisoDiasEl.textContent=’—’; }); el(‘imprimir’).addEventListener(‘click’, e => { e.preventDefault(); window.print(); }); })();