diff options
| author | Lucas Faria Mendes <lucas.fariamo08@gmail.com> | 2026-08-16 23:17:42 +0000 |
|---|---|---|
| committer | Lucas Faria Mendes <lucas.fariamo08@gmail.com> | 2026-08-16 23:17:42 +0000 |
| commit | 375482e654a01615683867e732ac9e458c7cbe74 (patch) | |
| tree | 12d1b31b8deb6bf8590bcdbc2cfb52dcc553e006 /api/src/utils/tax-calculator.ts | |
| parent | 2c2dfba45357bbd205a59145ae55a2779c911ae0 (diff) | |
| download | yaba-master.tar.gz yaba-master.zip | |
Signed-off-by: Lucas Faria Mendes <lucas.fariamo08@gmail.com>
Diffstat (limited to 'api/src/utils/tax-calculator.ts')
| -rw-r--r-- | api/src/utils/tax-calculator.ts | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/api/src/utils/tax-calculator.ts b/api/src/utils/tax-calculator.ts new file mode 100644 index 0000000..36ffc7e --- /dev/null +++ b/api/src/utils/tax-calculator.ts @@ -0,0 +1,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, + }; +} |