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
|
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);
}
|