aboutsummaryrefslogtreecommitdiff
path: root/src/utils/tax-calculator.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/utils/tax-calculator.ts')
-rw-r--r--src/utils/tax-calculator.ts85
1 files changed, 85 insertions, 0 deletions
diff --git a/src/utils/tax-calculator.ts b/src/utils/tax-calculator.ts
new file mode 100644
index 0000000..64b1c08
--- /dev/null
+++ b/src/utils/tax-calculator.ts
@@ -0,0 +1,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);
+}