[Lohnrechner-commits] r75 - trunk

scm-commit@wald.intevation.org scm-commit at wald.intevation.org
Tue Jan 15 18:43:20 CET 2008


Author: wilde
Date: 2008-01-15 18:43:20 +0100 (Tue, 15 Jan 2008)
New Revision: 75

Added:
   trunk/LST2008.py
Log:
LST2008 entsprechend dem aktuellen Programmablaufplan implementiert.

Copied: trunk/LST2008.py (from rev 73, trunk/LST2007.py)
===================================================================
--- trunk/LST2007.py	2007-01-26 11:50:39 UTC (rev 73)
+++ trunk/LST2008.py	2008-01-15 17:43:20 UTC (rev 75)
@@ -0,0 +1,903 @@
+# -*- coding: iso-8859-1 -*-
+# --------------------------------------------------------------------
+# LST2008 -- Python Modul zur Berechnung der Deutschen Lohnsteuer 2008
+# $Id$
+# --------------------------------------------------------------------
+#
+# Copyright (c) 2005, 2006, 2007, 2008 by Intevation GmbH
+# Authors:
+# Sascha Wilde <wilde at intevation.de>
+#
+# This program is free software under the GPL (>=v2)
+# Read the file COPYING coming with this package for details.
+
+"""Lohnsteuerberechnung nach dem offiziellen Programmablaufplan
+   wie im offiziellen Programmablaufplan des Bundesfinanzministerium
+   dokumentiert.
+   https://www.abgabenrechner.de/pruefdaten/pap2008.pdf"""
+
+__version__ = "$Revision$"
+# $Source:$
+
+def _ModulVersion():
+    return __version__[11:-2]
+
+# Die Variablen Namen sind hässlich, die Algorithmen nicht
+# dokumentiert, der Code grausam -- dafür entspricht alles Zeile für
+# Zeile obigem Dokument.  Jedenfalls sollte es so sein...
+
+from math import ceil, floor
+
+# Wir brauchen eigene Rundungsfunktionen mit definierter Präzision
+def FixedPointFloor(value, precision=2):
+    i = 10.0 ** precision
+    return floor(value * i) / i
+
+def FixedPointCeil(value, precision=2):
+    i = 10.0 ** precision
+    return ceil(value * i) / i
+
+# Ein paar Konstanten um das ganze etwas Benutzbarer zu machen:
+JAHR  = 1
+MONAT = 2
+WOCHE = 3
+TAG   = 4
+I   = 1
+II  = 2
+III = 3
+IV  = 4
+V   = 5
+VI  = 6
+
+class LST:
+    def __init__(self,
+                 AJAHR   =1964,
+                 ALTER1  =0,
+                 JFREIB  =0,
+                 JHINZU  =0,
+                 JRE4    =0,
+                 JVBEZ   =0,
+                 KRV     =0,
+                 LZZ     =2,
+                 LZZFREIB=0,
+                 LZZHINZU=0,
+                 R       =0,
+                 RE4     =0,
+                 SONSTB  =0,
+                 STERBE  =0,
+                 STKL    =1,
+                 VBEZ    =0,
+                 VBEZM   =0,
+                 VBEZS   =0,
+                 VBS     =0,
+                 VJAHR   =0,
+                 VKAPA   =0,
+                 VMT     =0,
+                 ZKF     =0,
+                 ZMVB    =0):
+        self.Set_AJAHR(AJAHR)
+        self.Set_ALTER1(ALTER1)
+        self.Set_JFREIB(JFREIB)
+        self.Set_JHINZU(JHINZU)
+        self.Set_JRE4(JRE4)
+        self.Set_JVBEZ(JVBEZ)
+        self.Set_KRV(KRV)
+        self.Set_LZZ(LZZ)
+        self.Set_LZZFREIB(LZZFREIB)
+        self.Set_LZZHINZU(LZZHINZU)
+        self.Set_R(R)
+        self.Set_RE4(RE4)
+        self.Set_SONSTB(SONSTB)
+        self.Set_STERBE(STERBE)
+        self.Set_STKL(STKL)
+        self.Set_VBEZ(VBEZ)
+        self.Set_VBEZM(VBEZM)
+        self.Set_VBEZS(VBEZS)
+        self.Set_VBS(VBS)
+        self.Set_VJAHR(VJAHR)
+        self.Set_VKAPA(VKAPA)
+        self.Set_VMT(VMT)
+        self.Set_ZKF(ZKF)
+        self.Set_ZMVB(ZMVB)
+        # Vorgegebene Ausgangsparameter
+        self.BK = 0
+        self.BKS = 0
+        self.BKV = 0
+        self.LSTLZZ = 0
+        self.SOLZLZZ = 0
+        self.SOLZS = 0
+        self.SOLZV = 0
+        self.STS = 0
+        self.STV = 0
+
+    def Calc(self):
+        """Berechnet die Lohnsteuer,
+        setzt BK, BKS, BKV, LSTLZZ, SOLZLZZ, SOLZS, SOLZV, STS und STV"""
+        # Interne Felder
+        # Laut Dokumentation sollen diese vor der Berechnung gelöscht werden,
+        # es ist mir nicht klar, ob das wirklich nötig ist...
+        self._ALTE = 0.0        # 2 Dezimalstellen
+        self._ANP = 0
+        self._ANTEIL1 = 0
+        self._ANTEIL2 = 0
+        self._BMG = 0.0         # 2 Dezimalstellen
+        self._DIFF = 0
+        self._EFA = 0
+        self._FVB = 0.0         # 2 Dezimalstellen
+        self._FVBSO = 0.0       # 2 Dezimalstellen
+        self._FVBZ = 0
+        self._FVBZSO = 0
+        self._FVBZOSO = 0
+        self._HBALTE = 0
+        self._HFVB = 0
+        self._HFVBZ = 0.0       # 2 Dezimalstellen
+        self._HFVBZSO = 0.0     # 2 Dezimalstellen
+        self._J = 0
+        self._JBMG = 0
+        self._JLFREIB = 0.0     # 2 Dezimalstellen
+        self._JLHINZU = 0.0     # 2 Dezimalstellen
+        self._JW = 0
+        self._K = 0
+        self._KENNVMT = 0
+        self._KFB = 0
+        self._KZTAB = 1
+        self._LSTJAHR = 0
+        self._LST1 = 0
+        self._LST2 = 0
+        self._LST3 = 0
+        self._LSTOSO = 0
+        self._LSTSO = 0
+        self._MIST = 0
+        self._RW = 0.0
+        self._SAP = 0
+        self._SOLZFREI = 0
+        self._SOLZJ = 0.0       # 2 Dezimalstellen
+        self._SOLZMIN = 0.0     # 2 Dezimalstellen
+        self._ST = 0
+        self._ST1 = 0
+        self._ST2 = 0
+        self._TAB1=(None,  # 1 als erstes Element, wie im PAP
+                    0.400, # bis 2005
+                    0.384, # 2006
+                    0.368, # 2007
+                    0.352, # 2008
+                    0.336, # 2009
+                    0.320, # 2010
+                    0.304, # 2011
+                    0.288, # 2012
+                    0.272, # 2013
+                    0.256, # 2014
+                    0.240, # 2015
+                    0.224, # 2016
+                    0.208, # 2017
+                    0.192, # 2018
+                    0.176, # 2019
+                    0.160, # 2020
+                    0.152, # 2021
+                    0.144, # 2022
+                    0.136, # 2023
+                    0.128, # 2024
+                    0.120, # 2025
+                    0.112, # 2026
+                    0.104, # 2027
+                    0.096, # 2028
+                    0.088, # 2029
+                    0.080, # 2030
+                    0.072, # 2031
+                    0.064, # 2032
+                    0.056, # 2033
+                    0.048, # 2034
+                    0.040, # 2035
+                    0.032, # 2036
+                    0.024, # 2037
+                    0.016, # 2038
+                    0.008, # 2039
+                    0.000) # 2040
+        self._TAB2=(None,  # 1 als erstes Element, wie im PAP
+                    3000,  # bis 2005
+                    2880,  # 2006
+                    2760,  # 2007
+                    2640,  # 2008
+                    2520,  # 2009
+                    2400,  # 2010
+                    2280,  # 2011
+                    2160,  # 2012
+                    2040,  # 2013
+                    1920,  # 2014
+                    1800,  # 2015
+                    1680,  # 2016
+                    1560,  # 2017
+                    1440,  # 2018
+                    1320,  # 2019
+                    1200,  # 2020
+                    1140,  # 2021
+                    1080,  # 2022
+                    1020,  # 2023
+                     960,  # 2024
+                     900,  # 2025
+                     840,  # 2026
+                     780,  # 2027
+                     720,  # 2028
+                     660,  # 2029
+                     600,  # 2030
+                     540,  # 2031
+                     480,  # 2032
+                     420,  # 2033
+                     360,  # 2034
+                     300,  # 2035
+                     240,  # 2036
+                     180,  # 2037
+                     120,  # 2038
+                      60,  # 2039
+                       0)  # 2040
+        self._TAB3=(None,  # 1 als erstes Element, wie im PAP
+                     900,  # bis 2005
+                     864,  # 2006
+                     828,  # 2007
+                     792,  # 2008
+                     756,  # 2009
+                     720,  # 2010
+                     684,  # 2011
+                     648,  # 2012
+                     612,  # 2013
+                     576,  # 2014
+                     540,  # 2015
+                     504,  # 2016
+                     468,  # 2017
+                     432,  # 2018
+                     396,  # 2019
+                     360,  # 2020
+                     342,  # 2021
+                     324,  # 2022
+                     306,  # 2023
+                     288,  # 2024
+                     270,  # 2025
+                     252,  # 2026
+                     234,  # 2027
+                     216,  # 2028
+                     198,  # 2029
+                     180,  # 2030
+                     162,  # 2031
+                     144,  # 2032
+                     126,  # 2033
+                     108,  # 2034
+                      90,  # 2035
+                      72,  # 2036
+                      54,  # 2037
+                      36,  # 2038
+                      18,  # 2039
+                       0)  # 2040
+        self._TAB4=self._TAB1
+        self._TAB5=(None,  # 1 als erstes Element, wie im PAP
+                    1900,  # bis 2005
+                    1824,  # 2006
+                    1748,  # 2007
+                    1672,  # 2008
+                    1596,  # 2009
+                    1520,  # 2010
+                    1444,  # 2011
+                    1368,  # 2012
+                    1292,  # 2013
+                    1216,  # 2014
+                    1140,  # 2015
+                    1064,  # 2016
+                     988,  # 2017
+                     912,  # 2018
+                     836,  # 2019
+                     760,  # 2020
+                     722,  # 2021
+                     684,  # 2022
+                     646,  # 2023
+                     608,  # 2024
+                     570,  # 2025
+                     532,  # 2026
+                     494,  # 2027
+                     456,  # 2028
+                     418,  # 2029
+                     380,  # 2030
+                     342,  # 2031
+                     304,  # 2032
+                     266,  # 2033
+                     228,  # 2034
+                     190,  # 2035
+                     152,  # 2036
+                     114,  # 2037
+                      76,  # 2038
+                      38,  # 2039
+                       0)  # 2040
+        self._VBEZB = 0
+        self._VBEZBSO = 0
+        self._VHB = 0
+        self._VSP = 0.0         # 2 Dezimalstellen
+        self._VSPN = 0
+        self._VSP1 = 0.0        # 2 Dezimalstellen
+        self._VSP2 = 0.0        # 2 Dezimalstellen
+        self._VSPKURZ = 0
+        self._VSPMAX1 = 0
+        self._VSPMAX2 = 0
+        self._VSPO = 0.0        # 2 Dezimalstellen
+        self._VSPREST = 0.0     # 2 Dezimalstellen
+        self._VSPVOR = 0.0      # 2 Dezimalstellen
+        self._X = 0.0           # 2 Dezimalstellen
+        self._Y = 0.0           # 6 Dezimalstellen
+        self._ZRE4 = 0.0        # 2 Dezimalstellen
+        self._ZRE4J = 0.0       # 2 Dezimalstellen
+        self._ZRE4OSO = 0.0     # 2 Dezimalstellen
+        self._ZRE4VMT = 0.0     # 2 Dezimalstellen
+        self._ZRE4VP = 0.0      # 2 Dezimalstellen
+        self._ZTABFB = 0.0      # 2 Dezimalstellen
+        self._ZTABFBOSO = 0.0   # 2 Dezimalstellen
+        self._ZVBEZ = 0.0       # 2 Dezimalstellen
+        self._ZVBEZJ = 0.0      # 2 Dezimalstellen
+        self._ZVE = 0.0         # 2 Dezimalstellen
+        self._ZX = 0
+        self._ZZX = 0
+        self._HOCH = 0
+        self._VERGL = 0
+        # ------------------------------------------------------------
+        # Anfang der Berechnung
+        self._MRE4JL()
+        self._MRE4()
+        self._MRE4ABZ()
+        self._MZTABFB()
+        self._KENNVMT = 0
+        self._MLSTJAHR()
+        self._LSTJAHR = self._ST
+        self._JW = self._LSTJAHR * 100
+        self._UPANTEIL()
+        self.LSTLZZ = self._ANTEIL1
+        if self.ZKF > 0:
+            self._ZTABFB += self._KFB
+            self._MLSTJAHR()
+            self._JBMG = self._ST
+        else:
+            self._JBMG = self._LSTJAHR
+        self._MSOLZ()
+        self._MSONST()
+        self._MVMT()
+
+    # Benutzte Unterprogramme:
+    def _MRE4JL(self):
+        if self.LZZ == 1:
+            self._ZRE4J = self.RE4 / 100
+            self._ZVBEZJ = self.VBEZ / 100
+            self._JLFREIB = self.LZZFREIB / 100
+            self._JLHINZU = self.LZZHINZU / 100
+        elif self.LZZ == 2:
+            self._ZRE4J = self.RE4 * 12 / 100
+            self._ZVBEZJ = self.VBEZ * 12 / 100
+            self._JLFREIB = self.LZZFREIB * 12 / 100
+            self._JLHINZU = self.LZZHINZU * 12 / 100
+        elif self.LZZ == 3:
+            self._ZRE4J = self.RE4 * 360 / 7 / 100
+            self._ZVBEZJ = self.VBEZ * 360 / 7 / 100
+            self._JLFREIB = self.LZZFREIB * 360 / 7 / 100
+            self._JLHINZU = self.LZZHINZU * 360 / 7 / 100
+        else:
+            self._ZRE4J = self.RE4 * 360 / 100
+            self._ZVBEZJ = self.VBEZ * 360 / 100
+            self._JLFREIB = self.LZZFREIB * 360 / 100
+            self._JLHINZU = self.LZZHINZU * 360 / 100
+
+    def _MRE4(self):
+        if (self._ZVBEZJ == 0):
+            self._FVBZ = 0
+            self._FVB = 0
+            self._FVBZSO = 0
+            self._FVBSO = 0
+        else:
+            if self.VJAHR < 2006:
+                self._J = 1
+            elif self.VJAHR < 2040:
+                self._J = self.VJAHR - 2004
+            else:
+                self._J = 36
+            if self.LZZ == 1:
+                self._VBEZB = self.VBEZM * self.ZMVB + self.VBEZS
+                self._HFVB = self._TAB2[self._J] / 12 * self.ZMVB
+                self._FVBZ = ceil(self._TAB3[self._J] / 12 * self.ZMVB)
+            else:
+                self._VBEZB = self.VBEZM * 12 + self.VBEZS
+                self._HFVB = self._TAB2[self._J]
+                self._FVBZ = self._TAB3[self._J]
+            self._FVB = self._VBEZB * self._TAB1[self._J] / 100
+            if self._FVB > self._HFVB:
+                self._FVB = self._HFVB
+            self._VBEZBSO = self.STERBE + self.VKAPA
+            self._FVBSO = FixedPointCeil(self._FVB + self._VBEZBSO 
+                                         * self._TAB1[self._J] / 100)
+            if self._FVBSO > self._TAB2[self._J]:
+                self._FVBSO = self._TAB2[self._J]
+            self._HFVBZSO = (self._VBEZB + self._VBEZBSO) / 100 - self._FVBSO
+            if self._TAB3[self._J] > self._HFVBZSO:
+                self._FVBSO = ceil(self._HFVBZSO)
+            else:
+                self._FVBSO = self._TAB3[self._J]
+            self._HFVBZ = self._VBEZB / 100 - self._FVB
+            if self._FVBZ > self._HFVBZ:
+                self._FVBZ = ceil(self._HFVBZ)
+        self._MRE4ALTE()
+
+    def _MRE4ALTE(self):
+        if self.ALTER1 == 0:
+            self._ALTE = 0
+        else:
+            if self.AJAHR < 2006:
+                self._K = 1
+            elif self.AJAHR < 2040:
+                self._K = self.AJAHR - 2004
+            else:
+                self._K = 36
+            self._BMG = self._ZRE4J - self._ZVBEZJ
+            self._ALTE = FixedPointCeil(self._BMG * self._TAB4[self._K])
+            self._HBALTE = self._TAB5[self._K]
+            if self._ALTE > self._HBALTE:
+                self._ALTE = self._HBALTE
+
+    def _MRE4ABZ(self):
+        self._ZRE4 = self._ZRE4J - self._FVB - self._ALTE - self._JLFREIB + self._JLHINZU
+        if self._ZRE4 < 0:
+            self._ZRE4 = 0
+        self._ZRE4VP = self._ZRE4J - self._FVB - self._ALTE
+        if self._ZRE4VP < 0:
+            self._ZRE4VP = 0;
+        self._ZVBEZ = self._ZVBEZJ - self._FVB
+        if self._ZVBEZ < 0:
+            self._ZVBEZ = 0
+
+    def _MZTABFB(self):
+        self._ANP = 0
+        if (self._ZVBEZ >= 0) and (self._ZVBEZ < self._FVBZ):
+            self._FVBZ = self._ZVBEZ
+        if (self.STKL < 6):
+            if (self._ZVBEZ > 0):
+                if (self._ZVBEZ - self._FVBZ) < 102:
+                    self._ANP = self._ZVBEZ - self._FVBZ
+                else:
+                    self._ANP = 102
+        else:
+            self._FVBZ = 0
+            self._FVBZSO = 0
+        if (self.STKL < 6) and (self._ZRE4 > self._ZVBEZ):
+            if (self._ZRE4 - self._ZVBEZ) < 920:
+                self._ANP += self._ZRE4 - self._ZVBEZ
+            else:
+                self._ANP += 920
+        self._KZTAB = 1
+        if self.STKL == 1:
+            self._SAP = 36
+            self._KFB = self.ZKF * 5808
+        elif self.STKL == 2:
+            self._EFA = 1308
+            self._SAP = 36
+            self._KFB = self.ZKF * 5808
+        elif self.STKL == 3:
+            self._KZTAB = 2
+            self._SAP = 72
+            self._KFB = self.ZKF * 5808
+        elif self.STKL == 4:
+            self._SAP = 36
+            self._KFB = self.ZKF * 2904
+        else:
+            self._KFB = 0
+        self._ZTABFB = self._EFA + self._ANP + self._SAP + self._FVBZ
+
+    def _MLSTJAHR(self):
+        if self.STKL < 5:
+            self._UPEVP()
+        else:
+            self._VSP = 0.0
+        if self._KENNVMT == 0:
+            self._ZVE = self._ZRE4 - self._ZTABFB - self._VSP
+        elif self._KENNVMT == 1:
+            self._ZVE = self._ZRE4OSO - self._ZTABFBOSO + self._ZRE4VMT - self._VSP
+        else:
+            self._ZVE = (self._ZRE4 - self._ZTABFB) / 5 - self._VSP
+        if self._ZVE < 1:
+            self._ZVE = self._X = 0.0
+        else:
+            self._X = floor(float(self._ZVE) / self._KZTAB)
+        if self.STKL < 5:
+            self._UPTAB07()
+        else:
+            self._MST5_6()
+
+    def _UPEVP(self):
+        if self.KRV > 0:
+            self._VSP1 = 0.0
+        else:
+            if self._ZRE4VP > 63600:
+                self._ZRE4VP = 63600
+            self._VSP1 = FixedPointFloor(0.32 * self._ZRE4VP)
+            self._VSP1 = FixedPointFloor(self._VSP1 * 0.0995)
+        self._VSP2 = FixedPointFloor(0.11 * self._ZRE4VP)
+        self._VHB = 1500 * self._KZTAB
+        if self._VSP2 > self._VHB:
+            self._VSP2 = self._VHB
+        self._VSPN = ceil(self._VSP1 + self._VSP2)
+        self._MVSP()
+        if self._VSPN > self._VSP:
+            self._VSP = self._VSPN
+
+    def _MVSP(self):
+        self._VSPO = self._ZRE4VP * 0.2
+        self._VSPVOR = 3068 * self._KZTAB
+        self._VSPMAX1 = 1334 * self._KZTAB
+        self._VSPMAX2 = 667 * self._KZTAB
+        self._VSPKURZ = 1134 * self._KZTAB
+        if self.KRV == 1:
+            if self._VSPO > self._VSPKURZ:
+                self._VSP = self._VSPKURZ
+            else:
+                self._VSP = floor(self._VSPO)
+        else:
+            self._UMVSP()
+
+    def _UMVSP(self):
+        self._VSPVOR -= self._ZRE4VP * 0.16
+        if self._VSPVOR < 0:
+            self._VSPVOR = 0.0
+        if self._VSPO > self._VSPVOR:
+            self._VSP = self._VSPVOR
+            self._VSPREST = self._VSPO - self._VSPVOR
+            if self._VSPREST > self._VSPMAX1:
+                self._VSP += self._VSPMAX1
+                self._VSPREST = FixedPointCeil((self._VSPREST - self._VSPMAX1) / 2.0)
+                if self._VSPREST > self._VSPMAX2:
+                    self._VSP = floor(self._VSP + self._VSPMAX2)
+                else:
+                    self._VSP = floor(self._VSP + self._VSPREST)
+            else:
+                self._VSP = floor(self._VSP + self._VSPREST)
+        else:
+            self._VSP = floor(self._VSPO)
+
+    def _MST5_6(self):
+        self._ZZX = self._X
+        if self._ZZX > 25812:
+            self._ZX = 25812
+            self._UP5_6()
+            if self._ZZX > 200000:
+                self._ST += (200000 - 25812) * 0.42
+                self._ST = floor(self._ST + (self._ZZX - 200000) * 0.45)
+            else:
+                self._ST = floor(self._ST + (self._ZZX - 25812) * 0.42)
+        else:
+            self._ZX = self._ZZX
+            self._UP5_6()
+            if self._ZZX > 9144:
+                self._VERGL = self._ST
+                self._ZX = 9144
+                self._UP5_6()
+                self._HOCH = floor(self._ST + (self._ZZX - 9144) * 0.42)
+                if self._HOCH < self._VERGL:
+                    self._ST = self._HOCH
+                else:
+                    self._ST = self._VERGL
+
+    def _UP5_6(self):
+        self._X = self._ZX * 1.25
+        self._UPTAB07()
+        self._ST1 = self._ST
+        self._X = self._ZX * 0.75
+        self._UPTAB07()
+        self._ST2 = self._ST
+        self._DIFF = (self._ST1 - self._ST2) * 2
+        self._MIST = floor(self._ZX * 0.15)
+        if self._MIST > self._DIFF:
+            self._ST = self._MIST
+        else:
+            self._ST = self._DIFF
+
+    def _MSOLZ(self):
+        self._SOLZFREI = 972 * self._KZTAB
+        if self._JBMG > self._SOLZFREI:
+            self._SOLZJ = FixedPointFloor(self._JBMG * 5.5 / 100.0)
+            self._SOLZMIN = (self._JBMG - self._SOLZFREI) * 20 / 100.0
+            if self._SOLZMIN < self._SOLZJ:
+                self._SOLZJ = self._SOLZMIN
+            self._JW = self._SOLZJ * 100
+            self._UPANTEIL()
+            self.SOLZLZZ = self._ANTEIL1
+        else:
+            self.SOLZLZZ = 0
+        if self.R > 0:
+            self._JW = self._JBMG * 100
+            self._UPANTEIL()
+            self.BK = self._ANTEIL1
+        else:
+            self.BK = 0
+
+    def _UPANTEIL(self):
+        if self.LZZ == 1:
+            self._ANTEIL1 = self._JW
+            self._ANTEIL2 = self._JW
+        elif self.LZZ == 2:
+            self._ANTEIL1 = floor(self._JW / 12.0)
+            self._ANTEIL2 = ceil(self._JW / 12.0)
+        elif self.LZZ == 3:
+            self._ANTEIL1 = floor(self._JW * 7 / 360.0)
+            self._ANTEIL2 = ceil(self._JW * 7 / 360.0)
+        else:
+            self._ANTEIL1 = floor(self._JW / 360.0)
+            self._ANTEIL2 = ceil(self._JW / 360.0)
+
+    def _UPTAB07(self):
+        if self._X < 7665:
+            self._ST = 0
+        elif self._X < 12740:
+            self._Y = (self._X - 7664) / 10000.0
+            self._RW = self._Y * 883.74
+            self._RW += 1500
+            self._ST = floor(self._RW * self._Y)
+        elif self._X < 52152:
+            self._Y = (self._X - 12739) / 10000.0
+            self._RW = self._Y * 228.74
+            self._RW += 2397
+            self._RW *= self._Y
+            self._ST = floor(self._RW + 989)
+        elif self._X < 250001:
+            self._ST = floor(self._X * 0.42 - 7914)
+        else:
+            self._ST = floor(self._X * 0.45 - 15414)
+        self._ST *= self._KZTAB
+
+    def _MSONST(self):
+        # ------------------------------
+        # Nicht im offiziellen Programm-
+        # ablaufplan: Attribute sichern
+        old_lzz = self.LZZ
+        # ------------------------------
+        self.LZZ = 1
+        if self.ZMVB == 0:
+            self.ZMVB = 12
+        if self.SONSTB == 0:
+            self._LSTSO = 0
+            self.STS = 0
+            self.SOLZS = 0
+            self.BKS = 0
+        else:
+            self._MOSONST()
+            self._ZRE4J = (self._ZRE4 + self.SONSTB) / 100
+            self._ZVBEZJ = (self._ZVBEZ + self.VBS) / 100
+            self._MRE4SONST()
+            self._MLSTJAHR()
+            self._LSTSO = self._ST * 100
+            self.STS = self._LSTSO - self._LSTOSO
+            if self.STS < 0:
+                self.STS = 0
+            self.SOLZS = floor(self.STS * 5.5 / 100)
+            if self.R > 0:
+                self.BKS = self.STS
+            else:
+                self.BKS = 0
+        # ------------------------------
+        # Nicht im offiziellen Programm-
+        # ablaufplan: Attribute
+        # wiederherstellen
+        self.LZZ = old_lzz
+        # ------------------------------
+
+    def _MVMT(self):
+        if self.VKAPA < 0:
+            self.VKAPA = 0
+        if (self.VMT + self.VKAPA) > 0:
+            if self._LSTOSO == 0:
+                self._MOSONST()
+                self._LSTOSO = self._LST1
+            else:
+                self._LSTSO = self._LST1
+            self._ZRE4OSO = self._ZRE4
+            self._ZTABFBOSO = self._ZTABFB
+            self._FVBZOSO = self._FVBZ
+            self._ZRE4J = (self._ZRE4 + self.SONSTB + self.VBS + self.VKAPA) / 100
+            self._MRE4SONST()
+            self._MLSTJAHR()
+            self._LST3 = self._ST * 100
+            self._ZTABFB = self._ZTABFB - self._FVBZ + self._FVBZOSO
+            self._KENNVMT = 1
+            if (self.RE4 + self.SONSTB - self.JFREIB + self.JHINZU) < 0:
+                self._KENNVMT = 2
+                self._MLSTJAHR()
+                self._LST2 = self._ST * 100
+                self.STV = self._LST2 * 5
+            else:
+                self._ZRE4VMT = (self.VMT / 100 + self.VKAPA / 100
+                                 - self._ZTABFB + self._ZTABFBOSO) / 5
+                self._MLSTJAHR()
+                self._LST2 = self._ST * 100
+                self.STV = (self._LST2 - self._LST1) * 5
+            self._LST3 -= self._LST1
+            if self._LST3 < self.STV:
+                self.STV = self._LST3
+            if self.STV < 0:
+                self.STV = 0
+            self.SOLZV = floor(self.STV * 5.5 / 100)
+            if self.R > 0:
+                self.BKV = self.STV
+            else:
+                self.BKV = 0
+        else:
+            self.STV = 0
+            self.SOLZV = 0
+            self.BKV = 0
+
+    def _MOSONST():
+        self._ZRE4J = self._ZRE4 / 100
+        self._ZVBEZJ = self._ZVBEZ / 100
+        self._JLFREIB = self.JFREIB / 100
+        self._JLHINZU = self.JHINZU / 100
+        self._MRE4()
+        self._MRE4ABZ()
+        self._MZTABFB()
+        self._MLSTJAHR()
+        self._LSTOSO = self._ST * 100
+
+    def _MRE4SONST():
+        self._MRE4()
+        self._FVBSO = self._FVB
+        self._MRE4ABZ()
+        self._FVBZSO = self._FVBZ
+        self._MZTABFB()
+
+    # Methoden zum geprüften setzen der Wert
+    # FIX ME: Prüfung _sehr_ unvollständig
+
+    def Set_AJAHR(self, value):
+        assert type(value) == type(0), "must be integer"
+        assert value >= 1900, "must be greater than 1900"
+        self.AJAHR = value
+
+    def Set_ALTER1(self, value):
+        assert value in (0,1), "must be 0 or 1"
+        self.ALTER1 = value
+
+    def Set_JFREIB(self, value):
+        self.JFREIB = value
+
+    def Set_JHINZU(self, value):
+        self.JHINZU = value
+
+    def Set_JRE4(self, value):
+        self.JRE4 = value
+
+    def Set_JVBEZ(self, value):
+        self.JVBEZ = value
+
+    def Set_KRV(self, value):
+        assert value in (0,1,2), "must be 0, 1 or 2"
+        self.KRV = value
+
+    def Set_LZZ(self, value):
+        assert value in (1,2,3,4), \
+               "must be in range 1-4 (JAHR, MONAT, WOCHE, TAG)"
+        self.LZZ = value
+
+    def Set_LZZFREIB(self, value):
+        self.LZZFREIB = value
+
+    def Set_LZZHINZU(self, value):
+        self.LZZHINZU = value
+
+    def Set_R(self, value):
+        assert value >= 0.0 and value <= 100.0, \
+               "must be in range 0.0-100.0 (Percent)"
+        self.R = value
+
+    def Set_RE4(self, value):
+        assert value >= 0, "must not be negative"
+        self.RE4 = value
+
+    def Set_SONSTB(self, value):
+        self.SONSTB = value
+
+    def Set_STERBE(self, value):
+        self.STERBE = value
+
+    def Set_STKL(self, value):
+        assert value in (1,2,3,4,5,6), \
+               "must be in range 1-6 (I II III IV V VI)"
+        self.STKL = value
+
+    def Set_VBEZ(self, value):
+        self.VBEZ = value
+
+    def Set_VBEZM(self, value):
+        self.VBEZM = value
+
+    def Set_VBEZS(self, value):
+        self.VBEZS = value
+
+    def Set_VBS(self, value):
+        self.VBS = value
+
+    def Set_VJAHR(self, value):
+        self.VJAHR = value
+
+    def Set_VKAPA(self, value):
+        self.VKAPA = value
+
+    def Set_VMT(self, value):
+        self.VMT = value
+
+    def Set_ZKF(self, value):
+        assert float(value) == float("%.1f" % value) and \
+               value >= 0, \
+               "must be positive, and must not have more than one decimal digit"
+        self.ZKF = value
+
+    def Set_ZMVB(self, value):
+        self.ZMVB = value
+
+# --------------------------------------------------------------------
+# Eine etwas schönere API
+#
+# FIX ME: Diese API berücksichtigt nicht alle Möglichen Parameter und
+# Berechnungen, es fehlen insbesondere die Berechnungen zu Mehrjährigen
+# Bezügen und Sonstigen Leistungen.
+
+class LStRechner2008(LST):
+    def __init__(self):
+        LST.__init__(self)
+
+    def SetGeb(self, geb):
+        """Setzt das Geburtsjahr"""
+        self.Set_AJAHR(geb + 65)
+        if self.AJAHR <= 2008:
+            self.Set_ALTER1(1)
+        else:
+            self.Set_ALTER1(0)
+
+    def SetLohn(self, lohn):
+        """Setzt Lohn in Euro.Cent"""
+        self.Set_RE4(round (lohn * 100.0))
+
+    def GetLohn(self):
+        """Liefert Lohn in Euro.Cent"""
+        return self.RE4 / 100.0
+
+    def SetZeitraum(self, lzz):
+        """Setzt Berechnungszeitraum (JAHR, MONAT, WOCHE, TAG)"""
+        self.Set_LZZ(lzz)
+
+    def GetZeitraum(self):
+        """Liefert Berechnungszeitraum (JAHR, MONAT, WOCHE, TAG)"""
+        return self.LZZ
+
+    def SetSteuerklasse(self, stkl):
+        """Setzt Steuerklasse (I, II, III, IV, V, VI)"""
+        self.Set_STKL(stkl)
+
+    def GetSteuerklasse(self):
+        """Liefert Steuerklasse (I, II, III, IV, V, VI)"""
+        return self.STKL
+
+    def SetKirchensteuerProzent(self, prozent):
+        """Setzt Kirchensteuer in Prozent,
+        0 wenn keine Kirchensteuer zu zahlen ist."""
+        self.Set_R(prozent)
+
+    def GetKirchensteuerProzent(self):
+        """Liefert Kirchensteuer in Prozent
+        oder 0 wenn keine Kirchensteuer zu zahlen ist."""
+        return self.R
+
+    def SetKinderfreibetrag(self, kfb):
+        """Setzt Kinderfreibetrag lt. Lohnsteuerkarte"""
+        self.Set_ZKF(kfb)
+
+    def GetKinderfreibetrag(self):
+        """Liefert Kinderfreibetrag lt. Lohnsteuerkarte"""
+        return self.ZFK
+
+    def GetLohnsteuer(self):
+        """Liefert Lohnsteuer in Euro.Cent"""
+        return round(self.LSTLZZ / 100, 2)
+
+    def GetSoli(self):
+        """Liefert Solidaritätszuschlag in Euro.Cent"""
+        return FixedPointFloor(self.SOLZLZZ / 100, 2)
+
+    def GetKirchensteuer(self):
+        """Liefert Kirchensteuer in Euro.Cent"""
+        return FixedPointFloor(self.BK * self.R / 10000, 2)



More information about the Lohnrechner-commits mailing list