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; 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 limiteAnterior = 0; for (const faixa of INSS_TABLE) { const baseNaFaixa = Math.min(salarioBruto, faixa.upTo) - limiteAnterior; if (baseNaFaixa <= 0) break; inss += baseNaFaixa * faixa.rate; limiteAnterior = faixa.upTo; } return parseFloat(inss.toFixed(2)); } interface FaixaIRRF { upTo: number | null; 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 }, ]; export function calcularIRRF(salarioBruto: number, inss: number): number { const base = salarioBruto - inss; if (base <= 0) return 0; const faixa = IRRF_TABLE.find((f) => f.upTo === null || base <= f.upTo)!; return parseFloat(Math.max(0, base * faixa.rate - faixa.deduction).toFixed(2)); } export interface ResultadoCalculo { salarioBruto: number; descontoINSS: number; descontoIRRF: number; totalDescontos: number; salarioLiquidoCalculado: number; } 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 }; } export function formatCurrency(value: number): string { return value.toLocaleString('pt-BR', { style: 'currency', currency: 'BRL', minimumFractionDigits: 2, }); } export function formatCurrencyCompact(value: number): string { if (Math.abs(value) >= 1_000) { return value.toLocaleString('pt-BR', { style: 'currency', currency: 'BRL', minimumFractionDigits: 0, maximumFractionDigits: 0, }); } return formatCurrency(value); }