Last active
November 22, 2023 17:12
-
-
Save troelskn/c00e0035139795409976df1c7f0026eb to your computer and use it in GitHub Desktop.
Danish tax calculations for Google sheets
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function DK_TAX_PARSE_OPTIONS(opts) { | |
var options = { | |
hasChildren: true, // Do you receive "børnepenge"? | |
isFamily: true, // Are you married (and your spouse without income)? | |
interests: 44256, // Deductible interests paid (typically on a mortgage) | |
churchTax: 0.00867, // Set your church tax rate here, if you are a member of the church. Otherwise set to 0.0 | |
municipalityTaxRate: 0.24926 // Find you tax rate here: https://www.skm.dk/skattetal/satser/kommuneskatter | |
}; | |
var applyOption = function(key, value) { | |
var key = key.trim(); | |
if (typeof value == "string") { | |
var value = value.trim(); | |
if (key == "hasChildren" || key == "isFamily") { | |
options[key] = value.toLowerCase() == "true"; | |
} else if (key == "churchTax" || key == "municipalityTaxRate") { | |
options[key] = parseFloat(value); | |
} else { | |
options[key] = parseInt(value); | |
} | |
} else { | |
options[key] = value; | |
} | |
}; | |
if (opts) { | |
if (typeof opts.forEach != "undefined") { | |
opts.forEach(function(row) { | |
applyOption(row[0], row[1]); | |
}); | |
} else { | |
opts.split(";").forEach(function(pair) { | |
var tmp = pair.split("="); | |
applyOption(tmp[0], tmp[1]); | |
}); | |
} | |
} | |
return options; | |
} | |
/** | |
* Calculate the remainder after PI taxes. | |
* + gross The gross income | |
* + grossOffset Previously taxed gross amount | |
* | |
* Antagelser (2019) | |
* | |
* AM bidrag (bruttoskat) 8% | |
* Personfradrag 2 x 46.200 | |
* Bundskat 12,16% | |
* Topskat over 513.400 15% | |
* Kommuneskat 24,926% | |
* Børnepenge over 782.600 2% | |
* Kirkeskat 0,867% | |
*/ | |
function DK_TAX_PERSONAL_INCOME(gross, grossOffset, options) { | |
var kommuneskat, bundskat, topskat, topskat_limit, toptopskat, toptopskat_limit, labour_deductions, deduction_limit, taxable, toptopskat_taxable, topskat_taxable, bundskat_taxable, net, netOffset; | |
options = DK_TAX_PARSE_OPTIONS(options); | |
if (typeof(grossOffset) == "number") { | |
netOffset = DK_TAX_PERSONAL_INCOME(grossOffset); | |
} else { | |
grossOffset = 0; | |
netOffset = 0; | |
} | |
gross += grossOffset; | |
kommuneskat = options.municipalityTaxRate; | |
bundskat = kommuneskat + 0.1213 + options.churchTax; | |
topskat = Math.min(bundskat + 0.155, 0.5205); | |
topskat_limit = 513400; | |
toptopskat = topskat + 0.02; | |
toptopskat_limit = options.hasChildren ? 782600 : 100000000; | |
labour_deductions = 37200 + 2100; // Andre fradrag: Beskæftigelse, Job | |
deduction_limit = 46200 * (options.isFamily ? 2 : 1); // Personfradrag | |
deduction_limit += options.interests * 0.336; // Fradrag for renter på lån | |
deduction_limit += labour_deductions * 0.249; | |
taxable = gross * 0.92; | |
if (taxable <= deduction_limit) { | |
return Math.round(taxable - netOffset); | |
} | |
taxable -= deduction_limit; | |
toptopskat_taxable = Math.max(0, taxable - toptopskat_limit); | |
topskat_taxable = Math.min(Math.max(0, taxable - topskat_limit), toptopskat_limit - topskat_limit); | |
bundskat_taxable = taxable - (topskat_taxable + toptopskat_taxable); | |
net = deduction_limit; | |
net += bundskat_taxable * (1.0 - bundskat); | |
net += topskat_taxable * (1.0 - topskat); | |
net += toptopskat_taxable * (1.0 - toptopskat); | |
return Math.round(net - netOffset); | |
} | |
/** | |
* Calculate the remainder after business taxes. | |
* + gross The gross income | |
*/ | |
function DK_TAX_BUSINESS(gross) { | |
return Math.round(gross * (1 - 0.22)); | |
} | |
/** | |
* Calculate the remainder after PAL tax on ratepension gains. | |
* + gross The gross gains | |
*/ | |
function DK_TAX_RATEPENSION(gross) { | |
return Math.round(gross * (1 - 0.153)); | |
} | |
/** | |
* Calculate the remainder tax on stock gains. | |
* + gross The gross gains | |
*/ | |
function DK_TAX_STOCK(gross, options) { | |
var limit, high, low; | |
options = DK_TAX_PARSE_OPTIONS(options); | |
limit = 54000 * (options.isFamily ? 2 : 1); | |
high = Math.max(0, gross - limit); | |
low = gross - high; | |
return Math.round((low * (1 - 0.27)) + (high * (1 - 0.42))); | |
} | |
/** | |
* Find the gross required to provide a given net | |
*/ | |
function DK_TAX_PERSONAL_INCOME_REVERSE(net) { | |
var result, gross, increment; | |
increment = 10000; | |
gross = increment; | |
while (true) { | |
result = DK_TAX_PERSONAL_INCOME(gross); | |
if (result >= net) { | |
return gross; | |
} | |
gross += increment; | |
} | |
} | |
/** | |
* Find the gross required to provide a given net | |
*/ | |
function DK_TAX_STOCK_REVERSE(net, options) { | |
var limit, net_limit, high, low; | |
options = DK_TAX_PARSE_OPTIONS(options); | |
limit = 54000 * (options.isFamily ? 2 : 1); | |
net_limit = limit * (1 - 0.27); | |
high = Math.max(0, net - net_limit); | |
low = net - high; | |
return Math.round((low / (1 - 0.27)) + (high / (1 - 0.42))); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment