Skip to content

Commit

Permalink
Add einkommensteuer for older years and fix rounding issues
Browse files Browse the repository at this point in the history
  • Loading branch information
mpm committed Mar 24, 2016
1 parent 7721db5 commit e3f7672
Show file tree
Hide file tree
Showing 2 changed files with 113 additions and 15 deletions.
73 changes: 64 additions & 9 deletions lib/taxger/einkommensteuer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,67 @@ def initialize(ekst, solz)
F = 10**-8

ZONES = {
# Values are taken from this table:
# https://de.wikipedia.org/wiki/Einkommensteuer_(Deutschland)#Entwicklung_der_Parameter
# Non-existent parameters for E(i) with i > 3 have to be replaced with nil
# Non-existent parameters for a(i) with i > 2 have to be 0.
'2010' => [
# E(0), a(1) * F, b(1), 0
[ 8_003, 912.17 * F, 0.14, 0],

# E(1), a(2) * F, b(2), S(1)
[ 13_469, 228.74 * F, 0.2397, 1038],

# E(2), a(3) (=0), b(3), S(2)
[ 52_881, 0, 0.42, 14_038.5],

# E(3), a(4) (=0), b(4), S(3)
[250_730, 0, 0.45, 97_134.5]
],

# no change from 2010
'2011' => [
[ 8_003, 912.17 * F, 0.14, 0],
[ 13_469, 228.74 * F, 0.2397, 1038],
[ 52_881, 0, 0.42, 14_038.5],
[250_730, 0, 0.45, 97_134.5]
],

# no change from 2010
'2012' => [
[ 8_003, 912.17 * F, 0.14, 0],
[ 13_469, 228.74 * F, 0.2397, 1038],
[ 52_881, 0, 0.42, 14_038.5],
[250_730, 0, 0.45, 97_134.5]
],

'2013' => [
[ 8_130, 933.70 * F, 0.14, 0],
[ 13_469, 228.74 * F, 0.2397, 1014],
[ 52_881, 0, 0.42, -8196 + 0.42 * 52_881],
[250_730, 0, 0.45, -15718 + 0.45 * 250_730]
],

'2014' => [
[ 8_354, 974.58 * F, 0.14, 0],
[ 13_469, 228.74 * F, 0.2397, 971],
[ 52_881, 0, 0.42, -8239 + 0.42 * 52_881],
[250_730, 0, 0.45, -15761 + 0.45 * 250_730]
],

'2015' => [
[ 8_473, 13_469, 997.6 * F, 0.14, 0, -8_472],
[ 13_470, 52_881, 228.74 * F, 0.2397, 948.68, -13_469],
[ 52_882, 250_730, 0, 0.42, 13_949, -52_881],
[250_731, nil, 0, 0.45, 97_045, -250_730]
]
[ 8_472, 997.6 * F, 0.14, 0],
[ 13_469, 228.74 * F, 0.2397, 948.68],
[ 52_881, 0, 0.42, 13_949],
[250_730, 0, 0.45, 97_045]
],

'2016' => [
[ 8_652, 993.62 * F, 0.14, 0],
[ 13_669, 225.40 * F, 0.2397, 952.48],
[ 53_665, 0, 0.42, -8394.14 + 0.42 * 53_665],
[254_447, 0, 0.45, -16027.52 + 0.45 * 254_447]
],
}

def calculate(year, income)
Expand All @@ -30,10 +85,10 @@ def calculate(year, income)

income = income * 0.01
ZONES[year.to_s].reverse.each do |zone|
(zone_start, zone_end, a, b, c, subs) = zone
if income >= zone_start
taxable = income + subs
tax = (a * (taxable * taxable) + b * taxable + c).to_i * 100
(zone_start, a, b, c) = zone
if income >= zone_start + 1
taxable = income - zone_start
tax = (a * (taxable ** 2) + b * taxable + c).to_i * 100

# Vereinfachte Berechnung des Solidaritätszuschlagsfreibetrags:
# Nicht gültig für Steuerklasse III (162 EUR statt 81 EUR) und abweichend,
Expand Down
55 changes: 49 additions & 6 deletions spec/einkommensteuer_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,56 @@ module Taxger
expect{ Einkommensteuer.calculate(2009, 0) }.to raise_exception(Einkommensteuer::Error)
end

# Reference values taken from https://www.bmf-steuerrechner.de/ekst/
[
['2015', 260_000_00, 101_216_00, 5_566_88],
['2015', 70_000_00, 21_138_00, 1_162_59],
['2015', 50_000_00, 12_757_00, 701_63],
['2015', 20_000_00, 2_611_00, 143_60],
['2015', 10_000_00, 237_00, 0],
['2015', 5_000_00, 0, 0]
[2010, 5_000_00, 0, 0],
[2010, 10_000_00, 315_00, 0],
[2010, 20_000_00, 2_701_00, 148_55],
[2010, 50_000_00, 12_847_00, 706_58],
[2010, 70_000_00, 21_228_00, 1_167_54],
[2010, 260_000_00, 101_306_00, 5_571_83],

[2011, 5_000_00, 0, 0],
[2011, 10_000_00, 315_00, 0],
[2011, 20_000_00, 2_701_00, 148_55],
[2011, 50_000_00, 12_847_00, 706_58],
[2011, 70_000_00, 21_228_00, 1_167_54],
[2011, 260_000_00, 101_306_00, 5_571_83],

[2012, 5_000_00, 0, 0],
[2012, 10_000_00, 315_00, 0],
[2012, 20_000_00, 2_701_00, 148_55],
[2012, 50_000_00, 12_847_00, 706_58],
[2012, 70_000_00, 21_228_00, 1_167_54],
[2012, 260_000_00, 101_306_00, 5_571_83],

[2013, 5_000_00, 0, 0],
[2013, 10_000_00, 294_00, 0],
[2013, 20_000_00, 2_677_00, 147_23],
[2013, 50_000_00, 12_823_00, 705_26],
[2013, 70_000_00, 21_204_00, 1_166_22],
[2013, 260_000_00, 101_282_00, 5_570_51],

[2014, 5_000_00, 0, 0],
[2014, 10_000_00, 256_00, 0],
[2014, 20_000_00, 2_634_00, 144_87],
[2014, 50_000_00, 12_780_00, 702_90],
[2014, 70_000_00, 21_161_00, 1_163_85],
[2014, 260_000_00, 101_239_00, 5_568_14],

[2015, 5_000_00, 0, 0],
[2015, 10_000_00, 237_00, 0],
[2015, 20_000_00, 2_611_00, 143_60],
[2015, 50_000_00, 12_757_00, 701_63],
[2015, 70_000_00, 21_138_00, 1_162_59],
[2015, 260_000_00, 101_216_00, 5_566_88],

[2016, 5_000_00, 0, 0],
[2016, 10_000_00, 206_00, 0],
[2016, 20_000_00, 2_560_00, 140_80],
[2016, 50_000_00, 12_636_00, 694_98],
[2016, 70_000_00, 21_005_00, 1_155_27],
[2016, 260_000_00, 100_972_00, 5_553_46]
].each do |dataset|
(year, brutto, ekst, solz) = dataset
it "calculates Einkommensteuer for #{brutto / 100.0} EUR in #{year}" do
Expand Down

0 comments on commit e3f7672

Please sign in to comment.