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

Contents of /trunk/RCS/LST2005.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 20 - (show annotations)
Fri Jan 14 11:44:48 2005 UTC (20 years, 3 months ago) by wilde
File MIME type: text/x-python
File size: 19877 byte(s)
Methode und assert zum setzen des Kinderfreibetrag hinzugef�gt

1 # -*- coding: iso-8859-1 -*-
2 # --------------------------------------------------------------------
3 # LST2005 -- Python Modul zur Berechnung der Deutschen Lohnsteuer 2005
4 # $Id$
5 # --------------------------------------------------------------------
6 #
7 # Copyright (c) 2005 by Intevation GmbH
8 # Authors:
9 # Sascha Wilde <[email protected]>
10 #
11 # This program is free software under the GPL (>=v2)
12 # Read the file COPYING coming with this package for details.
13
14 """Lohnsteuerberechnung nach dem offiziellen Programmablaufplan
15 wie in Programmablaufplan-LSt.pdf dokumentiert."""
16
17 __version__ = "$Revision$"
18 # $Source$
19
20 def _ModulVersion():
21 return __version__[11:-2]
22
23 # Die Variablen Namen sind hässlich, die Algorithmen nicht
24 # dokumentiert, der Code grausam -- dafür entspricht alles Zeile für
25 # Zeile obigem Dokument. Jedenfalls sollte es so sein...
26
27 from math import ceil, floor
28
29 # Wir brauchen eigene Rundungsfunktionen mit definierter Präzision
30 def FixedPointFloor(value, precision=2):
31 i = 10.0 ** precision
32 return floor(value * i) / i
33
34 def FixedPointCeil(value, precision=2):
35 i = 10.0 ** precision
36 return ceil(value * i) / i
37
38 # Ein paar Konstanten um das ganze etwas Benutzbarer zu machen:
39 JAHR = 1
40 MONAT = 2
41 WOCHE = 3
42 TAG = 4
43 I = 1
44 II = 2
45 III = 3
46 IV = 4
47 V = 5
48 VI = 6
49
50 class LST:
51 def __init__(self,
52 RE4=0,
53 ALTER1=0,
54 HINZUR=0,
55 JFREIB=0,
56 JHINZU=0,
57 JRE4 =0,
58 JVBEZ =0,
59 KRV =0,
60 LZZ =2,
61 R =0,
62 SONSTB=0,
63 STKL =1,
64 VBEZ =0,
65 VBEZM =0,
66 VBEZS =0,
67 VBS =0,
68 VMT =0,
69 WFUNDF=0,
70 ZKF =0,
71 ZMVB =0):
72 self.Set_RE4(RE4)
73 self.Set_ALTER1(ALTER1)
74 self.Set_HINZUR(HINZUR)
75 self.Set_JFREIB(JFREIB)
76 self.Set_JHINZU(JHINZU)
77 self.Set_JRE4(JRE4)
78 self.Set_JVBEZ(JVBEZ)
79 self.Set_KRV(KRV)
80 self.Set_LZZ(LZZ)
81 self.Set_R(R)
82 self.Set_SONSTB(SONSTB)
83 self.Set_STKL(STKL)
84 self.Set_VBEZ(VBEZ)
85 self.Set_VBEZM(VBEZM)
86 self.Set_VBEZS(VBEZS)
87 self.Set_VBS(VBS)
88 self.Set_VMT(VMT)
89 self.Set_WFUNDF(WFUNDF)
90 self.Set_ZKF(ZKF)
91 self.Set_ZMVB(ZMVB)
92 # Vorgegebene Ausgangsparameter
93 self.BK = 0
94 self.BKS = 0
95 self.BKV = 0
96 self.LSTLZZ = 0
97 self.SOLZLZZ = 0
98 self.SOLZS = 0
99 self.SOLZV = 0
100 self.STS = 0
101 self.STV = 0
102
103 def Calc(self):
104 """Berechnet die Lohnsteuer,
105 setzt BK, BKS, BKV, LSTLZZ, SOLZLZZ, SOLZS, SOLZV, STS und STV"""
106 # Interne Felder
107 # Laut Dokumentation sollen diese vor der Berechnung gelöscht werden,
108 # es ist mir nicht klar, ob das wirklich nötig ist...
109 self._ALTE = 0
110 self._ANP = 0
111 self._ANTEIL1 = 0
112 self._ANTEIL2 = 0
113 self._BMG = 0
114 self._DIFF = 0
115 self._EFA = 0
116 self._FVB = 0
117 self._FVBZ = 0
118 self._JBMG = 0
119 self._JW = 0
120 self._KENNZ = 0
121 self._KFB = 0
122 self._KZTAB = 1
123 self._LSTJAHR = 0
124 self._LST1 = 0
125 self._LST2 = 0
126 self._LST3 = 0
127 self._MIST = 0
128 self._RE4LZZ = 0
129 self._RE4LZZV = 0
130 self._RW = 0.0
131 self._SAP = 0
132 self._SOLZFREI = 0
133 self._SOLZJ = 0.0 # 2 Dezimalstellen
134 self._SOLZMIN = 0.0 # 2 Dezimalstellen
135 self._ST = 0
136 self._ST1 = 0
137 self._ST2 = 0
138 self._VBEZB = 0
139 self._VHB = 0
140 self._VSP = 0.0 # 2 Dezimalstellen
141 self._VSPN = 0
142 self._VSP1 = 0.0 # 2 Dezimalstellen
143 self._VSP2 = 0.0 # 2 Dezimalstellen
144 self._VSPKURZ = 0
145 self._VSPMAX1 = 0
146 self._VSPMAX2 = 0
147 self._VSPO = 0.0 # 2 Dezimalstellen
148 self._VSPREST = 0.0 # 2 Dezimalstellen
149 self._VSPVOR = 0.0 # 2 Dezimalstellen
150 # Jetzt wirds richtig toll: X und Y
151 # kann mal bitte jemand den Verantwortlichen für diese
152 # Variablen Namen schlagen?
153 self._X = 0.0 # 2 Dezimalstellen
154 self._Y = 0.0 # 6 Dezimalstellen
155 self._ZRE4 = 0.0 # 2 Dezimalstellen
156 self._ZRE4VP = 0.0 # 2 Dezimalstellen
157 self._ZRE4VP1 = 0.0 # 2 Dezimalstellen
158 self._ZTABFB = 0
159 self._ZVE = 0
160 self._ZX = 0
161 self._ZZX = 0
162 self._HOCH = 0
163 self._VERGL = 0
164 # ------------------------------------------------------------
165 # Anfang der Berechnung
166 self._MRE4LZZ()
167 self._RE4LZZ = self.RE4 - self._FVB \
168 - self._ALTE - self.WFUNDF \
169 + self.HINZUR
170 self._RE4LZZV = self.RE4 - self._FVB - self._ALTE
171 self._MRE4()
172 self._MZTABFB()
173 self._MLSTJAHR()
174 self._LSTJAHR = self._ST
175 self._JW = self._LSTJAHR * 100
176 self._UPANTEIL()
177 self.LSTLZZ = self._ANTEIL1
178 if self.ZKF > 0:
179 self._ZTABFB += self._KFB
180 self._MLSTJAHR()
181 self._JBMG = self._ST
182 else:
183 self._JBMG = self._LSTJAHR
184 self._MSOLZ()
185 self._MSONST()
186 self._MVMT()
187
188 # Benutzte Unterprogramme:
189 def _MRE4LZZ(self):
190 if self.VBEZ == 0:
191 self._FVBZ = 0
192 self._FVB = 0
193 else:
194 if self.LZZ == 1:
195 self._VBEZB = self.VBEZM * self.ZMVB + self.VBEZS
196 self._FVBZ = 75 * self.ZMVB
197 else:
198 self._VBEZB = self.VBEZM * 12 + self.VBEZS
199 self._FVBZ = 900
200 self._FVB = ceil(self._VBEZB * 0.4)
201 if self._FVB > 300000:
202 self._FVB = 300000
203 self._JW = self._FVB
204 self._UPANTEIL()
205 self._FVB = self._ANTEIL2
206 if self.ALTER1 == 0:
207 self._ALTE = 0
208 else:
209 self._BMG = self.RE4 - self.VBEZ
210 self._ALTE = ceil(self._BMG * 0.4)
211 self._JW = 190000
212 self._UPANTEIL()
213 if self._ALTE > self._ANTEIL2:
214 self._ALTE = self._ANTEIL2
215
216 def _MRE4(self):
217 if self.LZZ == 1:
218 self._ZRE4 = FixedPointFloor(self._RE4LZZ / 100.0)
219 self._ZRE4VP = FixedPointFloor(self._RE4LZZV / 100.0)
220 elif self.LZZ == 2:
221 self._ZRE4 = FixedPointFloor((self._RE4LZZ + 0.67) * 0.12)
222 self._ZRE4VP = FixedPointFloor((self._RE4LZZV + 0.67) * 0.12)
223 elif self.LZZ == 3:
224 self._ZRE4 = FixedPointFloor((self._RE4LZZ + 0.89) * 3.6 / 7)
225 self._ZRE4VP = FixedPointFloor((self._RE4LZZV + 0.89) * 3.6 / 7)
226 else:
227 self._ZRE4 = FixedPointFloor((self._RE4LZZ + 0.56) * 3.6)
228 self._ZRE4VP = FixedPointFloor((self._RE4LZZV + 0.56) * 3.6)
229 if self._ZRE4 < 0:
230 self._ZRE4 = 0.0
231
232 def _MZTABFB(self):
233 self._KZTAB = 1
234 if self.STKL < 6:
235 if self.VBEZ > 0:
236 self._ANP = 102
237 if self.RE4 > self.VBEZ:
238 self._ANP += 920
239 else:
240 self._ANP = 0
241 if self.STKL == 1:
242 self._SAP = 36
243 self._KFB = self.ZKF * 5808
244 elif self.STKL == 2:
245 self._EFA = 1308
246 self._SAP = 36
247 self._KFB = self.ZKF * 5808
248 elif self.STKL == 3:
249 self._KZTAB = 2
250 self._SAP = 72
251 self._KFB = self.ZKF * 5808
252 elif self.STKL == 4:
253 self._SAP = 36
254 self._KFB = self.ZKF * 2904
255 else:
256 self._KFB = 0
257 self._ZTABFB = self._EFA + self._ANP + self._SAP + self._FVBZ
258 self._KENNZ = 0
259
260 def _MLSTJAHR(self):
261 if self.STKL < 5:
262 self._UPEVP()
263 else:
264 self._VSP = 0.0
265 self._ZVE = self._ZRE4 - self._ZTABFB - self._VSP
266 if self._ZVE < 1:
267 self._ZVE = self._X = 0.0
268 else:
269 self._X = floor(float(self._ZVE) / self._KZTAB)
270 if self.STKL < 5:
271 self._UPTAB05()
272 else:
273 self._MST5_6()
274
275 def _UPEVP(self):
276 if self.KRV == 1:
277 self._VSP1 = 1.0
278 else:
279 if self._ZRE4VP > 62400:
280 self._ZRE4VP = 62400
281 self._VSP1 = 0.2 * self._ZRE4VP
282 self._VSP1 = FixedPointFloor(self._VSP1 * 0.0975)
283 self._VSP2 = FixedPointFloor(0.11 * self._ZRE4VP)
284 self._VHB = 1500 * self._KZTAB
285 if self._VSP2 > self._VHB:
286 self._VSP2 = self._VHB
287 self._VSPN = ceil(self._VSP1 + self._VSP2)
288 self._MVSP()
289 if self._VSPN > self._VSP:
290 self._VSP = self._VSPN
291
292 def _MVSP(self):
293 self._VSPO = self._ZRE4VP * 0.2
294 self._VSPVOR = 3068 * self._KZTAB
295 self._VSPMAX1 = 1334 * self._KZTAB
296 self._VSPMAX2 = 667 * self._KZTAB
297 self._VSPKURZ = 1134 * self._KZTAB
298 if self.KRV == 1:
299 if self._VSPO > self._VSPKURZ:
300 self._VSP = self._VSPKURZ
301 else:
302 self._VSP = ceil(self._VSPO)
303 else:
304 self._UMVSP()
305
306 def _UMVSP(self):
307 if self._KENNZ == 1:
308 self._VSPVOR = self._VSPVOR - self._ZRE4VP1 * 0.16
309 else:
310 self._VSPVOR = self._VSPVOR - self._ZRE4VP * 0.16
311 if self._VSPVOR < 0:
312 self._VSPVOR = 0.0
313 if self._VSPO > self._VSPVOR:
314 self._VSP = self._VSPVOR
315 self._VSPREST = self._VSPO - self._VSPVOR
316 if self._VSPREST > self._VSPMAX1:
317 self._VSP += self._VSPMAX1
318 self._VSPREST = FixedPointCeil((self._VSPREST - self._VSPMAX1) / 2.0)
319 if self._VSPREST > self._VSPMAX2:
320 self._VSP = ceil(self._VSP + self._VSPMAX2)
321 else:
322 self._VSP = ceil(self._VSP + self._VSPREST)
323 else:
324 self._VSP = ceil(self._VSP + self._VSPREST)
325 else:
326 self._VSP = ceil(self._VSPO)
327
328 def _MST5_6(self):
329 self._ZZX = self._X
330 if self._ZZX > 25812:
331 self._ZX = 25812
332 self._UP5_6()
333 self._ST = floor(self._ST + (self._ZZX - 25812) * 0.42)
334 else:
335 self._ZX = self._ZZX
336 self._UP5_6()
337 if self._ZZX > 9144:
338 self._VERGL = self._ST
339 self._ZX = 9144
340 self._UP5_6()
341 self._HOCH = floor(self._ST + (self._ZZX - 9144) * 0.42)
342 if self._HOCH < self._VERGL:
343 self._ST = self._HOCH
344 else:
345 self._ST = self._VERGL
346
347 def _UP5_6(self):
348 self._X = self._ZX * 1.25
349 self._UPTAB05()
350 self._ST1 = self._ST
351 self._X = self._ZX * 0.75
352 self._UPTAB05()
353 self._ST2 = self._ST
354 self._DIFF = (self._ST1 - self._ST2) * 2
355 self._MIST = floor(self._ZX * 0.15)
356 if self._MIST > self._DIFF:
357 self._ST = self._MIST
358 else:
359 self._ST = self._DIFF
360
361 def _MSOLZ(self):
362 self._SOLZFREI = 972 * self._KZTAB
363 if self._JBMG > self._SOLZFREI:
364 self._SOLZJ = FixedPointFloor(self._JBMG * 5.5 / 100.0)
365 self._SOLZMIN = (self._JBMG - self._SOLZFREI) * 20 / 100.0
366 if self._SOLZMIN < self._SOLZJ:
367 self._SOLZJ = self._SOLZMIN
368 self._JW = self._SOLZJ * 100
369 self._UPANTEIL()
370 self.SOLZLZZ = self._ANTEIL1
371 else:
372 self.SOLZLZZ = 0
373 if self.R > 0:
374 self._JW = self._JBMG * 100
375 self._UPANTEIL()
376 self.BK = self._ANTEIL1
377 else:
378 self.BK = 0
379
380 def _UPANTEIL(self):
381 if self.LZZ == 1:
382 self._ANTEIL1 = self._JW
383 self._ANTEIL2 = self._JW
384 elif self.LZZ == 2:
385 self._ANTEIL1 = floor(self._JW / 12.0)
386 self._ANTEIL2 = ceil(self._JW / 12.0)
387 elif self.LZZ == 3:
388 self._ANTEIL1 = floor(self._JW * 7 / 360.0)
389 self._ANTEIL2 = ceil(self._JW * 7 / 360.0)
390 else:
391 self._ANTEIL1 = floor(self._JW / 360.0)
392 self._ANTEIL2 = ceil(self._JW / 360.0)
393
394 def _UPTAB05(self):
395 if self._X < 7665:
396 self._ST = 0
397 elif self._X < 12740:
398 self._Y = (self._X - 7664) / 10000.0
399 self._RW = self._Y * 883.74
400 self._RW += 1500
401 self._ST = floor(self._RW * self._Y)
402 elif self._X < 52152:
403 self._Y = (self._X - 12739) / 10000.0
404 self._RW = self._Y * 228.74
405 self._RW += 2397
406 self._RW *= self._Y
407 self._ST = floor(self._RW + 989)
408 else:
409 self._ST = floor(self._X * 0.42 - 7914)
410 self._ST *= self._KZTAB
411
412 def _MSONST(self):
413 if self.SONSTB > 0:
414 # ------------------------------
415 # Nicht im offiziellen Programm-
416 # ablaufplan: Attribute sichern
417 old_lzz = self.LZZ
418 old_vbez = self.VBEZ
419 old_re4 = self.RE4
420 # ------------------------------
421 self.LZZ = 1
422 self.VBEZ = self.JVBEZ
423 self.RE4 = self.JRE4
424 self._MRE4LZZ()
425 self._MRE4LZZ2()
426 self._MRE4()
427 self._MZTABFB()
428 self._MLSTJAHR()
429 self._LST1 = self._ST * 100
430 self.VBEZ = self.JVBEZ + self.VBS
431 self.RE4 = self.JRE4 + self.SONSTB
432 self._MRE4LZZ()
433 self._MRE4LZZ2()
434 self._MRE4()
435 self._MLSTJAHR()
436 self._LST2 = self._ST * 100
437 self.STS = self._LST2 - self._LST1
438 self.SOLZS = self.STS * 5.5 / 100
439 if self.R > 0:
440 self.BKS = self.STS
441 else:
442 self.BKS = 0
443 # ------------------------------
444 # Nicht im offiziellen Programm-
445 # ablaufplan: Attribute
446 # wiederherstellen
447 self.LZZ = old_lzz
448 self.VBEZ = old_vbez
449 self.RE4 = old_re4
450 # ------------------------------
451 else:
452 self.STS = 0
453 self.SOLZS = 0
454 self.BKS = 0
455
456 def _MRE4LZZ2(self):
457 self._RE4LZZ = self.RE4 - self._FVB - self._ALTE \
458 - self.JFREIB + self.JHINZU
459 self._RE4LZZV = self.RE4 - self._FVB - self._ALTE
460
461 def _MVMT(self):
462 if self.VMT > 0:
463 # ------------------------------
464 # Nicht im offiziellen Programm-
465 # ablaufplan: Attribute sichern
466 old_lzz = self.LZZ
467 old_vbez = self.VBEZ
468 old_re4 = self.RE4
469 # ------------------------------
470 self.LZZ = 1
471 self.VBEZ = self.JVBEZ + self.VBS
472 self.RE4 = self.JRE4 + self.SONSTB
473 self._MRE4LZZ()
474 self._MRE4LZZ2()
475 self._MRE4()
476 self._MZTABFB()
477 self._MLSTJAHR()
478 self._LST1 = self._ST * 100
479 self.RE4 = self.JRE4 + self.SONSTB + self.VMT
480 self._MRE4LZZ()
481 self._MRE4LZZ2()
482 self._MRE4()
483 self._KENNZ = 1
484 self._ZRE4VP1 = self._ZRE4VP
485 self._MLSTJAHR()
486 self._LST3 = self._ST * 100
487 self.RE4 = self.JRE4 + self.SONSTB
488 self._MRE4LZZ()
489 self.RE4 = self.JRE4 + self.SONSTB + self.VMT / 5
490 self._MRE4LZZ2()
491 self._MRE4()
492 self._MLSTJAHR()
493 self._LST2 = self._ST * 100
494 self.STV = (self._LST2 - self._LST1) * 5
495 self._LST3 -= self._LST1
496 if self._LST3 < self.STV:
497 self.STV = self._LST3
498 self.SOLZV = floor(self.STV * 5.5 / 100)
499 if self.R > 0:
500 self.BKV = self.STV
501 else:
502 self.BKV = 0
503 # ------------------------------
504 # Nicht im offiziellen Programm-
505 # ablaufplan: Attribute
506 # wiederherstellen
507 self.LZZ = old_lzz
508 self.VBEZ = old_vbez
509 self.RE4 = old_re4
510 # ------------------------------
511 else:
512 self.STV = 0
513 self.SOLZV = 0
514 self.BKV = 0
515
516 # Methoden zum geprüften setzen der Wert
517 # FIX ME: Prüfung _sehr_ unvollständig
518 def Set_RE4(self, value):
519 assert value >= 0, "must not be negative"
520 self.RE4 = value
521
522 def Set_ALTER1(self, value):
523 assert value in (0,1), "must be 0 or 1"
524 self.ALTER1 = value
525
526 def Set_HINZUR(self, value):
527 self.HINZUR = value
528
529 def Set_JFREIB(self, value):
530 self.JFREIB = value
531
532 def Set_JHINZU(self, value):
533 self.JHINZU = value
534
535 def Set_JRE4(self, value):
536 self.JRE4 = value
537
538 def Set_JVBEZ(self, value):
539 self.JVBEZ = value
540
541 def Set_KRV(self, value):
542 assert value in (0,1), "must be 0 or 1"
543 self.KRV = value
544
545 def Set_LZZ(self, value):
546 assert value in (1,2,3,4), \
547 "must be in range 1-4 (JAHR, MONAT, WOCHE, TAG)"
548 self.LZZ = value
549
550 def Set_R(self, value):
551 assert value >= 0.0 and value <= 100.0, \
552 "must be in range 0.0-100.0 (Percent)"
553 self.R = value
554
555 def Set_SONSTB(self, value):
556 self.SONSTB = value
557
558 def Set_STKL(self, value):
559 assert value in (1,2,3,4,5,6), \
560 "must be in range 1-6 (I II III IV V VI)"
561 self.STKL = value
562
563 def Set_VBEZ(self, value):
564 self.VBEZ = value
565
566 def Set_VBEZM(self, value):
567 self.VBEZM = value
568
569 def Set_VBEZS(self, value):
570 self.VBEZS = value
571
572 def Set_VBS(self, value):
573 self.VBS = value
574
575 def Set_VMT(self, value):
576 self.VMT = value
577
578 def Set_WFUNDF(self, value):
579 self.WFUNDF = value
580
581 def Set_ZKF(self, value):
582 assert float(value) == float("%.1f" % value) and \
583 value >= 0, \
584 "must be positive, and must not have more than one decimal digit"
585 self.ZKF = value
586
587 def Set_ZMVB(self, value):
588 self.ZMVB = value
589
590 # --------------------------------------------------------------------
591 # Eine etwas schönere API
592 #
593 # FIX ME: Diese API berücksichtigt nicht alle Möglichen Parameter und
594 # Berechnungen, es fehlen insbesondere die Berechnungen zu Mehrjährigen
595 # Bezügen und Sonstigen Leistungen.
596
597 class LStRechner2005(LST):
598 def __init__(self):
599 LST.__init__(self)
600
601 def SetLohn(self, lohn):
602 """Setzt Lohn in Euro.Cent"""
603 self.Set_RE4(lohn * 100.0)
604
605 def SetZeitraum(self, lzz):
606 """Setzt Berechnungszeitraum (JAHR, MONAT, WOCHE, TAG)"""
607 self.Set_LZZ(lzz)
608
609 def SetSteuerklasse(self, stkl):
610 """Setzt Steuerklasse (I, II, III, IV, V, VI)"""
611 self.Set_STKL(stkl)
612
613 def SetKirchensteuer(self, prozent):
614 """Setzt Kirchensteuer in Prozent"""
615 self.Set_R(prozent)
616
617 def SetKinderfreibetrag(self, kfb):
618 """Setzt Kinderfreibetrag lt. Lohnsteuerkarte"""
619 self.Set_ZKF(kfb)
620
621 def GetLohnsteuer(self):
622 """Liefert Lohnsteuer in Euro.Cent"""
623 return round(self.LSTLZZ / 100, 2)
624
625 def GetSoli(self):
626 """Liefert Solidaritätszuschlag in Euro.Cent"""
627 return FixedPointFloor(self.SOLZLZZ / 100, 2)
628
629 def GetKirchensteuer(self):
630 """Liefert Kirchensteuer in Euro.Cent"""
631 return FixedPointFloor(self.BK * self.R / 10000, 2)

Properties

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26