diff options
| author | Lucas Faria Mendes <lucas.fariamo08@gmail.com> | 2026-08-14 18:06:35 +0000 |
|---|---|---|
| committer | Lucas Faria Mendes <lucas.fariamo08@gmail.com> | 2026-08-14 18:06:35 +0000 |
| commit | 2c2dfba45357bbd205a59145ae55a2779c911ae0 (patch) | |
| tree | 0736b848aed56ec2da3c2489c49da0519447703d /src/utils | |
| download | yaba-2c2dfba45357bbd205a59145ae55a2779c911ae0.tar.gz yaba-2c2dfba45357bbd205a59145ae55a2779c911ae0.zip | |
remake
Signed-off-by: Lucas Faria Mendes <lucas.fariamo08@gmail.com>
Diffstat (limited to 'src/utils')
| -rw-r--r-- | src/utils/tax-calculator.ts | 85 |
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); +} |