diff --git a/lib/taxger/einkommensteuer.rb b/lib/taxger/einkommensteuer.rb index 02c2ed2..9e059c5 100644 --- a/lib/taxger/einkommensteuer.rb +++ b/lib/taxger/einkommensteuer.rb @@ -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) @@ -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, diff --git a/spec/einkommensteuer_spec.rb b/spec/einkommensteuer_spec.rb index 87e209b..2469991 100644 --- a/spec/einkommensteuer_spec.rb +++ b/spec/einkommensteuer_spec.rb @@ -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