Skip to content

Instantly share code, notes, and snippets.

@lucaspar
Last active January 22, 2024 16:04
Show Gist options
  • Save lucaspar/2c20754b37920217678cebb64170cb7a to your computer and use it in GitHub Desktop.
Save lucaspar/2c20754b37920217678cebb64170cb7a to your computer and use it in GitHub Desktop.
Cálculo de IR em JavaScript com teste unitário.
/* Fonte: https://gist.github.com/lucaspar/2c20754b37920217678cebb64170cb7a */
/**
* Calcula o imposto de renda sobre o valor de rendimentos tributáveis,
* conforme tabela progressiva do ano tributário de 2023, seguindo a
* incidência mensal do imposto sobre a renda de pessoas físicas (IRPF).
*
* @params {Number} rendimentos Renda a ser tributada, em R$.
* @returns {Number} imposto a pagar sobre `rendimentos`, em R$.
**/
function IRRF(rendimentos, aplicarDescontoSimplificado = false) {
// Aliquotas à partir de maio de 2023:
// Fonte: https://www.gov.br/receitafederal/pt-br/assuntos/meu-imposto-de-renda/tabelas/2023
const aliquotas = [0, 0.075, 0.15, 0.225, 0.275]; // aliquotas de IR
const bases = [2112.00, 2826.65, 3751.05, 4664.68, Infinity]; // bases de calculo
// novo desconto simplificado mensal, introduzido em 2023, corresponde à
// 25% da faixa inicial da base de calculo e é opcional.
const descontoSimplificado = 0.25 * bases[0];
// aplicar desconto simplificado, se solicitado
if (aplicarDescontoSimplificado) {
rendimentos -= descontoSimplificado;
}
// Aliquotas anteriores para referência: de 2016 à abril de 2023
// Fonte: https://www.gov.br/receitafederal/pt-br/assuntos/meu-imposto-de-renda/tabelas/2016
// const aliquotas_antigas = [0, 0.075, 0.15, 0.225, 0.275]; // aliquotas de IR
// const bases_antigas = [1903.98, 2826.65, 3751.05, 4664.68, Infinity]; // bases de calculo
// calcula tamanho das faixas de tributacao conforme rendimentos
const faixas = bases.map(function(b, i, arr) {
// a faixa atual eh no maximo o valor da base de calculo
var faixa = Math.min(rendimentos, b)
// se a base nao for a primeira, precisamos subtrair o valor da base anterior
if (i !== 0) {
faixa -= arr[i - 1];
}
// bases maiores que rendimentos podem resultar em faixas negativas, por isso zeramos essas
faixa = Math.max(faixa, 0);
return faixa;
});
// calcula imposto conforme a aliquota de cada faixa e soma ao valor total
const imposto = faixas.reduce( function(sum, f, i) {
// calcula imposto da faixa multiplicando sua aliquota
const impFaixa = (f * aliquotas[i]);
return sum += impFaixa;
}, 0 );
// imposto a pagar sobre rendimentos
return imposto;
}
/**
* Testa função IRRF com valores previamente simulados.
* Referências:
* - Alíquotas: https://www.gov.br/receitafederal/pt-br/assuntos/orientacao-tributaria/tributos/irpf-imposto-de-renda-pessoa-fisica#tabelas-de-incid-ncia-mensal
* - Simulador: https://www27.receita.fazenda.gov.br/simulador-irpf/
*
* @returns {Boolean} Verdadeiro se teste foi bem sucedido.
**/
function testIRRF() {
const depoisDe2023 = true
// se verdadeiro, usa tabela de 2023 em diante e desconto simplificado,
// senao usa valores de 2016 à abril de 2023
let groundTruths
// valores de teste
const inputs = [1500.00, 2500.00, 3500.00, 4500.00, 5500.00, 2826.67, 2826.68, 2826.69];
if (depoisDe2023) {
// valores-verdade obtidos por simulacao
groundTruths = [ 0.00, 0.00, 75.40, 241.97, 482.34, 14.00, 14.00, 14.00];
} else {
// valores de 2016 à abril de 2023
groundTruths = [ 0.00, 44.7, 170.20, 376.37, 643.14, 69.20, 69.20, 69.21];
}
// calcula IR
const resultsNew = inputs.map(function(v) {
const res = IRRF(v, depoisDe2023);
return Math.round(100 * res) / 100;
});
const isApproved = resultsNew.reduce(function(passedPrevious, r, i) {
// avalia resultado
const passedCurrent = (r === groundTruths[i]);
if (!passedCurrent) {
// debug test case
console.error("FAILED - test case", i + 1, "expected", groundTruths[i], "but got", r);
}
// sticky false: previous and current tests must have been successful
return passedPrevious && passedCurrent;
}, true);
if (isApproved) {
console.log("IR test result: SUCCESS");
}
return isApproved;
}
testIRRF();
@lucaspar
Copy link
Author

lucaspar commented Apr 24, 2019

Implementação em JavaScript do cálculo do Imposto de Renda sobre rendimentos mensais conforme tabela progressiva de 2023 da Receita Federal + teste de implementação conforme simulações de cálculo.

Referências:

Contribuições são bem-vindas. 🙂

@lucaspar
Copy link
Author

lucaspar commented Aug 4, 2022

2023-12-20

  • Atualizado com alíquotas a partir de maio de 2023 e novo desconto simplificado.

2022-08-04

  • Atualizadas referências com links quebrados.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment