/[lohnrechner]/trunk/RCS/LST2005.py
ViewVC logotype

Annotation of /trunk/RCS/LST2005.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2 - (hide annotations)
Tue Jan 11 15:22:31 2005 UTC (20 years, 3 months ago) by wilde
File MIME type: text/x-python
File size: 14913 byte(s)
Initial revision

1 wilde 2 # --------------------------------------------------------------------
2     # LST2005 -- Python Modul zur Berechnung der Deutschen Lohnsteuer 2005
3     # $Id$
4     # --------------------------------------------------------------------
5     #
6     # Copyright (c) 2005 by Intevation GmbH
7     # Authors:
8     # Sascha Wilde <[email protected]>
9     #
10     # This program is free software under the GPL (>=v2)
11     # Read the file COPYING coming with this package for details.
12    
13     """Lohnsteuerberechnung nach dem offiziellen Programmablaufplan
14     wie in Programmablaufplan-LSt.pdf dokumentiert."""
15    
16     # Die Variablen Namen sind hässlich, die Algorithmen nicht
17     # dokumentiert, der Code grausam -- dafür entspricht alles Zeile für
18     # Zeile obigem Dokument. Jedenfalls sollte es so sein...
19    
20     from math import ceil, floor
21    
22     # Wir brauchen eigene Rundungsfunktionen mit definierter Präzision
23     def FixedPointFloor(value, precision=2):
24     i = 10.0 ** precision
25     return floor(value * i) / i
26    
27     def FixedPointCeil(value, precision=2):
28     i = 10.0 ** precision
29     return ceil(value * i) / i
30    
31     # Ein paar Konstanten um das ganze etwas Benutzbarer zu machen:
32     JAHR = 1
33     MONAT = 2
34     WOCHE = 3
35     TAG = 4
36     I = 1
37     II = 2
38     III = 3
39     IV = 4
40     V = 5
41     VI = 6
42    
43     class LST:
44     def __init__(self,
45     RE4=0,
46     ALTER1=0,
47     HINZUR=0,
48     JFREIB=0,
49     JHINZU=0,
50     JRE4 =0,
51     JVBEZ =0,
52     KRV =0,
53     LZZ =2,
54     R =0,
55     SONSTB=0,
56     STKL =1,
57     VBEZ =0,
58     VBEZM =0,
59     VBEZS =0,
60     VBS =0,
61     VMT =0,
62     WFUNDF=0,
63     ZKF =0,
64     ZMVB =0):
65     self.Set_RE4(RE4)
66     self.Set_ALTER1(ALTER1)
67     self.Set_HINZUR(HINZUR)
68     self.Set_JFREIB(JFREIB)
69     self.Set_JHINZU(JHINZU)
70     self.Set_JRE4(JRE4)
71     self.Set_JVBEZ(JVBEZ)
72     self.Set_KRV(KRV)
73     self.Set_LZZ(LZZ)
74     self.Set_R(R)
75     self.Set_SONSTB(SONSTB)
76     self.Set_STKL(STKL)
77     self.Set_VBEZ(VBEZ)
78     self.Set_VBEZM(VBEZM)
79     self.Set_VBEZS(VBEZS)
80     self.Set_VBS(VBS)
81     self.Set_VMT(VMT)
82     self.Set_WFUNDF(WFUNDF)
83     self.Set_ZKF(ZKF)
84     self.Set_ZMVB(ZMVB)
85     # Vorgegebene Ausgangsparameter
86     self.BK = 0
87     self.BKS = 0
88     self.BKV = 0
89     self.LSTLZZ = 0
90     self.SOLZLZZ = 0
91     self.SOLZS = 0
92     self.SOLZV = 0
93     self.STS = 0
94     self.STV = 0
95    
96     def Calc(self):
97     """Berechnet die Lohnsteuer,
98     setzt BK, BKS, BKV, LSTLZZ, SOLZLZZ, SOLZS, SOLZV, STS und STV"""
99     # Interne Felder
100     # Laut Dokumentation sollen diese vor der Berechnung gelöscht werden,
101     # es ist mir nicht klar, ob das wirklich nötig ist...
102     self._ALTE = 0
103     self._ANP = 0
104     self._ANTEIL1 = 0
105     self._ANTEIL2 = 0
106     self._BMG = 0
107     self._DIFF = 0
108     self._EFA = 0
109     self._FVB = 0
110     self._FVBZ = 0
111     self._JBMG = 0
112     self._JW = 0
113     self._KENNZ = 0
114     self._KFB = 0
115     self._KZTAB = 1
116     self._LSTJAHR = 0
117     self._LST1 = 0
118     self._LST2 = 0
119     self._LST3 = 0
120     self._MIST = 0
121     self._RE4LZZ = 0
122     self._RE4LZZV = 0
123     self._RW = 0.0
124     self._SAP = 0
125     self._SOLZFREI = 0
126     self._SOLZJ = 0.0 # 2 Dezimalstellen
127     self._SOLZMIN = 0.0 # 2 Dezimalstellen
128     self._ST = 0
129     self._ST1 = 0
130     self._ST2 = 0
131     self._VBEZB = 0
132     self._VHB = 0
133     self._VSP = 0.0 # 2 Dezimalstellen
134     self._VSPN = 0
135     self._VSP1 = 0.0 # 2 Dezimalstellen
136     self._VSP2 = 0.0 # 2 Dezimalstellen
137     self._VSPKURZ = 0
138     self._VSPMAX1 = 0
139     self._VSPMAX2 = 0
140     self._VSPO = 0.0 # 2 Dezimalstellen
141     self._VSPREST = 0.0 # 2 Dezimalstellen
142     self._VSPVOR = 0.0 # 2 Dezimalstellen
143     # Jetzt wirds richtig toll: X und Y
144     # kann mal bitte jemand den Verantwortlichen für diese
145     # Variablen Namen schlagen?
146     self._X = 0.0 # 2 Dezimalstellen
147     self._Y = 0.0 # 6 Dezimalstellen
148     self._ZRE4 = 0.0 # 2 Dezimalstellen
149     self._ZRE4VP = 0.0 # 2 Dezimalstellen
150     self._ZRE4VP1 = 0.0 # 2 Dezimalstellen
151     self._ZTABFB = 0
152     self._ZVE = 0
153     self._ZX = 0
154     self._ZZX = 0
155     self._HOCH = 0
156     self._VERGL = 0
157     # ------------------------------------------------------------
158     # Anfang der Berechnung
159     self._MRE4LZZ()
160     self._RE4LZZ = self.RE4 - self._FVB \
161     - self._ALTE - self.WFUNDF \
162     + self.HINZUR
163     self._RE4LZZV = self.RE4 - self._FVB - self._ALTE
164     self._MRE4()
165     self._MZTABFB()
166     self._MLSTJAHR()
167     self._LSTJAHR = self._ST
168     self._JW = self._LSTJAHR * 100
169     self._UPANTEIL()
170     self.LSTLZZ = self._ANTEIL1
171     if self.ZKF > 0:
172     self._ZTABFB += self._KFB
173     self._MLSTJAHR()
174     self._JBMG = self._ST
175     else:
176     self._JBMG = self._LSTJAHR
177     self._MSOLZ()
178     # self._MSONST()
179     # self._MVMT()
180    
181     # Benutzte Unterprogramme:
182     def _MRE4LZZ(self):
183     if self.VBEZ == 0:
184     self._FVBZ = 0
185     self._FVB = 0
186     else:
187     if self.LZZ == 1:
188     self._VBEZB = self.VBEZM * self.ZMVB + self.VBEZS
189     self._FVBZ = 75 * self.ZMVB
190     else:
191     self._VBEZB = self.VBEZM * 12 + self.VBEZS
192     self._FVBZ = 900
193     self._FVB = ceil(self._VBEZB * 0.4)
194     if self._FVB > 300000:
195     self._FVB = 300000
196     self._JW = self._FVB
197     self._UPANTEIL()
198     self._FVB = self._ANTEIL2
199     if self.ALTER1 == 0:
200     self._ALTE = 0
201     else:
202     self._BMG = self.RE4 - self.VBEZ
203     self._ALTE = ceil(self._BMG * 0.4)
204     self._JW = 190000
205     self._UPANTEIL()
206     if self._ALTE > self._ANTEIL2:
207     self._ALTE = self._ANTEIL2
208    
209     def _MRE4(self):
210     if self.LZZ == 1:
211     self._ZRE4 = FixedPointFloor(self._RE4LZZ / 100.0)
212     self._ZRE4VP = FixedPointFloor(self._RE4LZZV / 100.0)
213     elif self.LZZ == 2:
214     self._ZRE4 = FixedPointFloor((self._RE4LZZ + 0.67) * 0.12)
215     self._ZRE4VP = FixedPointFloor((self._RE4LZZV + 0.67) * 0.12)
216     elif self.LZZ == 3:
217     self._ZRE4 = FixedPointFloor((self._RE4LZZ + 0.89) * 3.6 / 7)
218     self._ZRE4VP = FixedPointFloor((self._RE4LZZV + 0.89) * 3.6 / 7)
219     else:
220     self._ZRE4 = FixedPointFloor((self._RE4LZZ + 0.56) * 3.6)
221     self._ZRE4VP = FixedPointFloor((self._RE4LZZV + 0.56) * 3.6)
222     if self._ZRE4 < 0:
223     self._ZRE4 = 0.0
224    
225     def _MZTABFB(self):
226     self._KZTAB = 1
227     if self.STKL < 6:
228     if self.VBEZ > 0:
229     self._ANP = 102
230     if self.RE4 > self.VBEZ:
231     self._ANP += 920
232     else:
233     self._ANP = 0
234     if self.STKL == 1:
235     self._SAP = 36
236     self._KFB = self.ZKF * 5808
237     elif self.STKL == 2:
238     self._EFA = 1308
239     self._SAP = 36
240     self._KFB = self.ZKF * 5808
241     elif self.STKL == 3:
242     self._KZTAB = 2
243     self._SAP = 72
244     self._KFB = self.ZKF * 5808
245     elif self.STKL == 4:
246     self._SAP = 36
247     self._KFB = self.ZKF * 2904
248     else:
249     self._KFB = 0
250     self._ZTABFB = self._EFA + self._ANP + self._SAP + self._FVBZ
251     self._KENNZ = 0
252    
253     def _MLSTJAHR(self):
254     if self.STKL < 5:
255     self._UPEVP()
256     else:
257     self._VSP = 0.0
258     self._ZVE = self._ZRE4 - self._ZTABFB - self._VSP
259     if self._ZVE < 1:
260     self._ZVE = self._X = 0.0
261     else:
262     self._X = floor(float(self._ZVE) / self._KZTAB)
263     if self.STKL < 5:
264     self._UPTAB05()
265     else:
266     self._MST5_6()
267    
268     def _UPEVP(self):
269     if self.KRV == 1:
270     self._VSP1 = 1.0
271     else:
272     if self._ZRE4VP > 62400:
273     self._ZRE4VP = 62400.0
274     self._VSP1 = 0.2 * self._ZRE4VP
275     self._VSP1 = self._VSP1 * 0.0975
276     self._VSP2 = 0.11 * self._ZRE4VP
277     self._VHB = 1500 * self._KZTAB
278     if self._VSP2 > self._VHB:
279     self._VSP2 = self._VHB
280     self._VSPN = ceil(self._VSP1 + self._VSP2)
281     self._MVSP()
282     if self._VSPN > self._VSP:
283     self._VSP = self._VSPN
284    
285     def _MVSP(self):
286     self._VSPO = self._ZRE4VP * 0.2
287     self._VSPVOR = 3068 * self._KZTAB
288     self._VSPMAX1 = 1334 * self._KZTAB
289     self._VSPMAX2 = 667 * self._KZTAB
290     self._VSPKURZ = 1134 * self._KZTAB
291     if self.KRV == 1:
292     if self._VSPO > self._VSPKURZ:
293     self._VSP = self._VSPKURZ
294     else:
295     self._VSP = ceil(self._VSPO)
296     else:
297     self._UMVSP()
298    
299     def _UMVSP(self):
300     if self._KENNZ == 1:
301     self._VSPVOR = self._VSPVOR - self._ZRE4VP1 * 0.16
302     else:
303     self._VSPVOR = self._VSPVOR - self._ZRE4VP * 0.16
304     if self._VSPVOR < 0:
305     self._VSPVOR = 0.0
306     if self._VSPO > self._VSPVOR:
307     self._VSP = self._VSPVOR
308     self._VSPREST = self._VSPO - self._VSPVOR
309     if self._VSPREST > self._VSPMAX1:
310     self._VSP += self._VSPMAX1
311     self._VSPREST = FixedPointCeil((self._VSPREST - self._VSPMAX1) / 2.0)
312     if self._VSPREST > self._VSPMAX2:
313     self._VSP = ceil(self._VSP + self._VSPMAX2)
314     else:
315     self._VSP = ceil(self._VSP + self._VSPREST)
316     else:
317     self._VSP = ceil(self._VSP + self._VSPREST)
318     else:
319     self._VSP = ceil(self._VSPO)
320    
321     def _MST5_6(self):
322     self._ZZX = self._X
323     if self._ZZX > 25812:
324     self._ZX = 25812
325     self._UP5_6()
326     self._ST = floor(self._ST + (self._ZZX - 25812) * 0.42)
327     else:
328     self._ZX = self._ZZX
329     self._UP5_6()
330     if self._ZZX > 9144:
331     self._VERGL = self._ST
332     self._ZX = 9144
333     self._UP5_6()
334     self._HOCH = floor(self._ST + (self._ZZX - 9144) * 0.42)
335     if self._HOCH < self._VERGL:
336     self._ST = self._HOCH
337     else:
338     self._ST = self._VERGL
339    
340     def _UP5_6(self):
341     self._X = self._ZX * 1.25
342     self._UPTAB05()
343     self._ST1 = self._ST
344     self._X = self._ZX * 0.75
345     self._UPTAB05()
346     self._ST2 = self._ST
347     self._DIFF = (self._ST1 - self._ST2) * 2
348     self._MIST = floor(self._ZX * 0.15)
349     if self._MIST > self._DIFF:
350     self._ST = self._MIST
351     else:
352     self._ST = self._DIFF
353    
354     def _MSOLZ(self):
355     self._SOLZFREI = 972 * self._KZTAB
356     if self._JBMG > self._SOLZFREI:
357     self._SOLZJ = FixedPointFloor(self._JBMG * 5.5 / 100.0)
358     self._SOLZMIN = (self._JBMG - self._SOLZFREI) * 20 / 100.0
359     if self._SOLZMIN < self._SOLZJ:
360     self._SOLZJ = self._SOLZMIN
361     self._JW = self._SOLZJ * 100
362     self._UPANTEIL()
363     self.SOLZLZZ = self._ANTEIL1
364     else:
365     self.SOLZLZZ = 0
366     if self.R > 0:
367     self._JW = self._JBMG * 100
368     self._UPANTEIL
369     self.BK = self._ANTEIL1
370     else:
371     self.BK = 0
372    
373     def _UPANTEIL(self):
374     if self.LZZ == 1:
375     self._ANTEIL1 = self._JW
376     self._ANTEIL2 = self._JW
377     elif self.LZZ == 2:
378     self._ANTEIL1 = floor(self._JW / 12.0)
379     self._ANTEIL2 = ceil(self._JW / 12.0)
380     elif self.LZZ == 3:
381     self._ANTEIL1 = floor(self._JW * 7 / 360.0)
382     self._ANTEIL2 = ceil(self._JW * 7 / 360.0)
383     else:
384     self._ANTEIL1 = floor(self._JW / 360.0)
385     self._ANTEIL2 = ceil(self._JW / 360.0)
386    
387     def _UPTAB05(self):
388     if self._X < 7665:
389     self._ST = 0
390     elif self._X < 12740:
391     self._Y = (self._X - 7664) / 10000.0
392     self._RW = self._Y * 883.74
393     self._RW += 1500
394     self._ST = floor(self._RW * self._Y)
395     elif self._X < 52152:
396     self._Y = (self._X - 12739) / 10000.0
397     self._RW = self._Y * 228.74
398     self._RW += 2397
399     self._RW *= self._Y
400     self._ST = floor(self._RW + 989)
401     else:
402     self._ST = floor(self._X * 0.42 - 7914)
403     self._ST *= self._KZTAB
404    
405     # Methoden zum geprüften setzen der Wert
406     # FIX ME: Prüfung _sehr_ unvollständig
407     def Set_RE4(self, value):
408     assert value >= 0, "must not be negative"
409     self.RE4 = value
410    
411     def Set_ALTER1(self, value):
412     assert value in (0,1), "must be 0 or 1"
413     self.ALTER1 = value
414    
415     def Set_HINZUR(self, value):
416     self.HINZUR = value
417    
418     def Set_JFREIB(self, value):
419     self.JFREIB = value
420    
421     def Set_JHINZU(self, value):
422     self.JHINZU = value
423    
424     def Set_JRE4(self, value):
425     self.JRE4 = value
426    
427     def Set_JVBEZ(self, value):
428     self.JVBEZ = value
429    
430     def Set_KRV(self, value):
431     if value not in (0,1):
432     raise ValueError
433     self.KRV = value
434    
435     def Set_LZZ(self, value):
436     if value not in (1,2,3,4):
437     raise ValueError
438     self.LZZ = value
439    
440     def Set_R(self, value):
441     self.R = value
442    
443     def Set_SONSTB(self, value):
444     self.SONSTB = value
445    
446     def Set_STKL(self, value):
447     if value not in (1,2,3,4,5,6):
448     raise ValueError
449     self.STKL = value
450    
451     def Set_VBEZ(self, value):
452     self.VBEZ = value
453    
454     def Set_VBEZM(self, value):
455     self.VBEZM = value
456    
457     def Set_VBEZS(self, value):
458     self.VBEZS = value
459    
460     def Set_VBS(self, value):
461     self.VBS = value
462    
463     def Set_VMT(self, value):
464     self.VMT = value
465    
466     def Set_WFUNDF(self, value):
467     self.WFUNDF = value
468    
469     def Set_ZKF(self, value):
470     self.ZKF = value
471    
472     def Set_ZMVB(self, value):
473     self.ZMVB = value
474    
475     # --------------------------------------------------------------------
476     # Eine etwas schönere API:
477     #
478    
479     def Set_Lohn(self, lohn):
480     self.Set_RE4(lohn * 100.0)
481    
482     def Set_Zeitraum(self, lzz):
483     self.Set_LZZ(lzz)
484    
485     def Set_Steuerklasse(self, stkl):
486     self.Set_STKL(stkl)
487    
488     def Get_Lohnsteuer(self):
489     return round(self.LSTLZZ / 100, 2)
490    

Properties

Name Value
svn:eol-style native
svn:keywords Author Date Id Revision

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26