/** * Calculadora de impostos brasileiros (INSS + IRRF). * Tabelas vigentes: 2025. * * IMPORTANTE: As alíquotas e faixas mudam anualmente por decreto. * Verifique a legislação vigente a cada ano fiscal. * * Fonte: Portaria MPS / IN RFB 2.141/2023 e atualizações. */ // --------------------------------------------------------------------------- // INSS — Tabela Progressiva 2025 // --------------------------------------------------------------------------- const INSS_TABLE = [ { upTo: 1_518.0, rate: 0.075 }, { upTo: 2_793.88, rate: 0.09 }, { upTo: 4_190.83, rate: 0.12 }, { upTo: 8_157.41, rate: 0.14 }, ] as const; const INSS_TETO = 908.86; // Valor máximo de desconto do INSS /** * Calcula o desconto do INSS com a tabela progressiva. * Cada faixa incide apenas sobre a parte do salário dentro dela. */ export function calcularINSS(salarioBruto: number): number { if (salarioBruto <= 0) return 0; if (salarioBruto > INSS_TABLE[INSS_TABLE.length - 1].upTo) return INSS_TETO; let inss = 0; let salarioRestante = salarioBruto; let limiteAnterior = 0; for (const faixa of INSS_TABLE) { if (salarioRestante <= 0) break; const baseNaFaixa = Math.min(salarioBruto, faixa.upTo) - limiteAnterior; inss += baseNaFaixa * faixa.rate; salarioRestante -= baseNaFaixa; limiteAnterior = faixa.upTo; } return parseFloat(inss.toFixed(2)); } // --------------------------------------------------------------------------- // IRRF — Tabela Progressiva 2025 // --------------------------------------------------------------------------- interface FaixaIRRF { upTo: number | null; // null = sem limite superior rate: number; deduction: number; } const IRRF_TABLE: FaixaIRRF[] = [ { upTo: 2_259.2, rate: 0, deduction: 0 }, { upTo: 2_826.65, rate: 0.075, deduction: 169.44 }, { upTo: 3_751.05, rate: 0.15, deduction: 381.44 }, { upTo: 4_664.68, rate: 0.225, deduction: 662.77 }, { upTo: null, rate: 0.275, deduction: 896.0 }, ]; /** * Calcula o desconto do IRRF. * Base de cálculo: Salário Bruto − INSS (sem considerar dependentes). */ export function calcularIRRF(salarioBruto: number, inss: number): number { const baseCalculo = salarioBruto - inss; if (baseCalculo <= 0) return 0; const faixa = IRRF_TABLE.find( (f) => f.upTo === null || baseCalculo <= f.upTo, )!; const irrf = baseCalculo * faixa.rate - faixa.deduction; return parseFloat(Math.max(0, irrf).toFixed(2)); } // --------------------------------------------------------------------------- // Resultado consolidado // --------------------------------------------------------------------------- export interface ResultadoCalculo { salarioBruto: number; descontoINSS: number; descontoIRRF: number; totalDescontos: number; salarioLiquidoCalculado: number; } /** * Calcula o salário líquido completo a partir do salário bruto. * Retorna um objeto com o detalhamento de cada desconto. */ export function calcularSalarioLiquido(salarioBruto: number): ResultadoCalculo { const descontoINSS = calcularINSS(salarioBruto); const descontoIRRF = calcularIRRF(salarioBruto, descontoINSS); const totalDescontos = parseFloat((descontoINSS + descontoIRRF).toFixed(2)); const salarioLiquidoCalculado = parseFloat( (salarioBruto - totalDescontos).toFixed(2), ); return { salarioBruto, descontoINSS, descontoIRRF, totalDescontos, salarioLiquidoCalculado, }; }