1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
|
/**
* 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,
};
}
|