@equisoft/tax-ca
Advanced tools
Comparing version 2021.1.5 to 2021.2.0
@@ -29,4 +29,4 @@ import { FederalCode, ProvinceCode } from '../misc/code-types'; | ||
export declare function getMaxFederalMarginalRate(provincialCode: ProvinceCode): number; | ||
export declare function getTotalMaxMarginalRate(provincialCode: ProvinceCode): string; | ||
export declare function getTotalMaxMarginalRate(provincialCode: ProvinceCode): number; | ||
export declare function getTotalTaxAmount(provincialCode: ProvinceCode, grossIncome: number, inflationRate?: number, yearsToInflate?: number): number; | ||
export declare function calculateEffectiveTaxRate(income: number, province: ProvinceCode): number; |
@@ -14,2 +14,3 @@ "use strict"; | ||
const code_types_1 = require("../misc/code-types"); | ||
const utils_1 = require("../utils"); | ||
const collections_1 = require("../utils/collections"); | ||
@@ -440,65 +441,71 @@ exports.TAX_BRACKETS = { | ||
}; | ||
function inflate(amount, inflationRate, yearsToInflate) { | ||
return amount * (Math.pow((1 + inflationRate), yearsToInflate)); | ||
} | ||
function extractRate(rates, income, inflationRate, yearsToInflate) { | ||
let tax = 0; | ||
rates.forEach((bracket) => { | ||
const bracketFrom = bracket.FROM * (Math.pow((1 + inflationRate), yearsToInflate)); | ||
if (bracketFrom < income) { | ||
const bracketTo = bracket.TO * (Math.pow((1 + inflationRate), yearsToInflate)); | ||
tax += (Math.min(income, bracketTo) - bracketFrom) * bracket.RATE; | ||
} | ||
}); | ||
return tax; | ||
const reducer = (previous, current) => { | ||
const bracketFrom = inflate(current.FROM, inflationRate, yearsToInflate); | ||
const bracketTo = inflate(current.TO, inflationRate, yearsToInflate); | ||
const bracketTax = bracketFrom < income ? (Math.min(income, bracketTo) - bracketFrom) * current.RATE : 0; | ||
return previous + bracketTax; | ||
}; | ||
return rates.reduce(reducer, 0); | ||
} | ||
function getTaxRates(code) { | ||
return exports.TAX_BRACKETS[code].RATES; | ||
} | ||
function getAbatement(code) { | ||
return exports.TAX_BRACKETS[code].ABATEMENT; | ||
} | ||
function getSurtaxRates(code) { | ||
return exports.TAX_BRACKETS[code].SURTAX_RATES; | ||
} | ||
function getRate(brackets, grossIncome, inflationRate, yearsToInflate) { | ||
const reducer = (previous, current) => { | ||
const bracketFrom = inflate(current.FROM, inflationRate, yearsToInflate); | ||
return bracketFrom < grossIncome ? current.RATE : previous; | ||
}; | ||
return brackets.reduce(reducer, 0); | ||
} | ||
function getFederalTaxAmount(grossIncome, inflationRate = 0, yearsToInflate = 0) { | ||
return extractRate(exports.TAX_BRACKETS.CA.RATES, grossIncome, inflationRate, yearsToInflate); | ||
return extractRate(getTaxRates(code_types_1.FEDERAL_CODE), grossIncome, inflationRate, yearsToInflate); | ||
} | ||
exports.getFederalTaxAmount = getFederalTaxAmount; | ||
function getProvincialTaxAmount(province, grossIncome, inflationRate = 0, yearsToInflate = 0) { | ||
return extractRate(exports.TAX_BRACKETS[province].RATES, grossIncome, inflationRate, yearsToInflate); | ||
return extractRate(getTaxRates(province), grossIncome, inflationRate, yearsToInflate); | ||
} | ||
exports.getProvincialTaxAmount = getProvincialTaxAmount; | ||
function getProvincialSurtaxAmount(province, baseTaxAmount, inflationRate = 0, yearsToInflate = 0) { | ||
return extractRate(exports.TAX_BRACKETS[province].SURTAX_RATES, baseTaxAmount, inflationRate, yearsToInflate); | ||
return extractRate(getSurtaxRates(province), baseTaxAmount, inflationRate, yearsToInflate); | ||
} | ||
exports.getProvincialSurtaxAmount = getProvincialSurtaxAmount; | ||
function getFederalBaseCredit(inflationRate, yearsToInflate) { | ||
return exports.TAX_BRACKETS.CA.BASE_TAX_CREDIT | ||
* exports.TAX_BRACKETS.CA.TAX_CREDIT_RATE | ||
* (Math.pow((1 + inflationRate), yearsToInflate)); | ||
const baseTaxCredit = exports.TAX_BRACKETS.CA.BASE_TAX_CREDIT * exports.TAX_BRACKETS.CA.TAX_CREDIT_RATE; | ||
return inflate(baseTaxCredit, inflationRate, yearsToInflate); | ||
} | ||
exports.getFederalBaseCredit = getFederalBaseCredit; | ||
function getProvincialAbatement(province, federalTaxAmount) { | ||
return exports.TAX_BRACKETS[province].ABATEMENT * federalTaxAmount; | ||
return getAbatement(province) * federalTaxAmount; | ||
} | ||
exports.getProvincialAbatement = getProvincialAbatement; | ||
function getFederalMarginalRate(provincialCode, grossIncome, inflationRate = 0, yearsToInflate = 0) { | ||
const fedTax = getFederalTaxAmount(grossIncome, inflationRate, yearsToInflate); | ||
const fedBaseCredit = getFederalBaseCredit(inflationRate, yearsToInflate); | ||
const fedProvAbatement = getProvincialAbatement(provincialCode, fedTax - fedBaseCredit); | ||
return grossIncome <= 0 ? 0 : Math.max(fedTax - fedBaseCredit - fedProvAbatement, 0) / grossIncome; | ||
const brackets = getTaxRates(code_types_1.FEDERAL_CODE); | ||
const rate = getRate(brackets, grossIncome, inflationRate, yearsToInflate); | ||
return rate * (1 - getAbatement(provincialCode)); | ||
} | ||
exports.getFederalMarginalRate = getFederalMarginalRate; | ||
function getProvincialMarginalRate(provincialCode, grossIncome, inflationRate = 0, yearsToInflate = 0) { | ||
let marginalRate = 0; | ||
const baseTaxAmount = getProvincialTaxAmount(provincialCode, grossIncome, inflationRate, yearsToInflate); | ||
exports.TAX_BRACKETS[provincialCode].RATES.forEach(bracket => { | ||
const bracketFrom = bracket.FROM * (Math.pow((1 + inflationRate), yearsToInflate)); | ||
if (bracketFrom < grossIncome) { | ||
marginalRate = bracket.RATE; | ||
} | ||
}); | ||
let surtaxRate = 0; | ||
exports.TAX_BRACKETS[provincialCode].SURTAX_RATES.forEach(bracket => { | ||
const bracketFrom = bracket.FROM * (Math.pow((1 + inflationRate), yearsToInflate)); | ||
if (bracketFrom < baseTaxAmount) { | ||
surtaxRate = bracket.RATE; | ||
} | ||
}); | ||
return marginalRate * (1 + surtaxRate); | ||
const taxAmount = getProvincialTaxAmount(provincialCode, grossIncome, inflationRate, yearsToInflate); | ||
const taxCredit = getProvincialBaseCredit(provincialCode, inflationRate, yearsToInflate); | ||
const provincialTaxAmount = Math.max(taxAmount - taxCredit, 0); | ||
const taxBrackets = getTaxRates(provincialCode); | ||
const surtaxBrackets = getSurtaxRates(provincialCode); | ||
const taxRate = getRate(taxBrackets, grossIncome, inflationRate, yearsToInflate); | ||
const surtaxRate = getRate(surtaxBrackets, provincialTaxAmount, inflationRate, yearsToInflate); | ||
return taxRate + (taxRate * surtaxRate); | ||
} | ||
exports.getProvincialMarginalRate = getProvincialMarginalRate; | ||
function getProvincialBaseCredit(province, inflationRate, yearsToInflate) { | ||
return exports.TAX_BRACKETS[province].BASE_TAX_CREDIT | ||
* exports.TAX_BRACKETS[province].RATES[0].RATE | ||
* (Math.pow((1 + inflationRate), yearsToInflate)); | ||
const baseTaxCredit = exports.TAX_BRACKETS[province].BASE_TAX_CREDIT * exports.TAX_BRACKETS[province].RATES[0].RATE; | ||
return inflate(baseTaxCredit, inflationRate, yearsToInflate); | ||
} | ||
@@ -509,3 +516,3 @@ exports.getProvincialBaseCredit = getProvincialBaseCredit; | ||
const fedRate = getFederalMarginalRate(provincialCode, grossIncome, inflationRate, yearsToInflate); | ||
return provRate + fedRate; | ||
return utils_1.roundToPrecision(provRate + fedRate, 4); | ||
} | ||
@@ -515,6 +522,6 @@ exports.getTotalMarginalRate = getTotalMarginalRate; | ||
// tslint:disable-next-line:no-non-null-assertion | ||
const marginalRate = collections_1.maxBy(exports.TAX_BRACKETS[provincialCode].RATES, (bracket) => bracket.TO).RATE; | ||
const marginalRate = collections_1.maxBy(getTaxRates(provincialCode), (bracket) => bracket.TO).RATE; | ||
// tslint:disable-next-line:no-non-null-assertion | ||
const surtaxRate = collections_1.maxBy(exports.TAX_BRACKETS[provincialCode].SURTAX_RATES, bracket => bracket.TO).RATE; | ||
return marginalRate * (1 + surtaxRate); | ||
const surtaxRate = collections_1.maxBy(getSurtaxRates(provincialCode), bracket => bracket.TO).RATE; | ||
return marginalRate + (marginalRate * surtaxRate); | ||
} | ||
@@ -524,4 +531,4 @@ exports.getMaxProvincialMarginalRate = getMaxProvincialMarginalRate; | ||
// tslint:disable-next-line:no-non-null-assertion | ||
const maxRate = collections_1.maxBy(exports.TAX_BRACKETS[code_types_1.FEDERAL_CODE].RATES, bracket => bracket.TO).RATE; | ||
return maxRate * (1 - exports.TAX_BRACKETS[provincialCode].ABATEMENT); | ||
const maxRate = collections_1.maxBy(getTaxRates(code_types_1.FEDERAL_CODE), bracket => bracket.TO).RATE; | ||
return maxRate * (1 - getAbatement(provincialCode)); | ||
} | ||
@@ -532,3 +539,3 @@ exports.getMaxFederalMarginalRate = getMaxFederalMarginalRate; | ||
const fedRate = getMaxFederalMarginalRate(provincialCode); | ||
return (provRate + fedRate).toPrecision(4); | ||
return utils_1.roundToPrecision(provRate + fedRate, 4); | ||
} | ||
@@ -535,0 +542,0 @@ exports.getTotalMaxMarginalRate = getTotalMaxMarginalRate; |
{ | ||
"name": "@equisoft/tax-ca", | ||
"version": "2021.1.5", | ||
"version": "2021.2.0", | ||
"description": "Canadian tax data and calculation functions.", | ||
@@ -5,0 +5,0 @@ "main": "dist/index.js", |
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
65176
1980
0