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

Diff of /trunk/lohnrechner.py

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

trunk/RCS/lohnrechner.py revision 12 by wilde, Thu Jan 13 11:39:49 2005 UTC trunk/lohnrechner.py revision 81 by frank, Wed Feb 11 11:04:42 2009 UTC
# Line 1  Line 1 
1  #! /usr/bin/python  #! /usr/bin/python
2    # -*- coding: iso-8859-1 -*-
3  # --------------------------------------------------------------------  # --------------------------------------------------------------------
4  # Lohnsteuer und Sozialabgaben Rechner  # Lohnsteuer und Sozialabgaben Rechner
5  # $Id$  # $Id$
6  # --------------------------------------------------------------------  # --------------------------------------------------------------------
7  #  #
8  # Copyright (c) 2005 by Intevation GmbH  # Copyright (c) 2005,2006,2007,2008 by Intevation GmbH
9  # Authors:  # Authors:
10  # Sascha Wilde <[email protected]>  # Sascha Wilde <[email protected]>
11  #  #
12  # This program is free software under the GPL (>=v2)  # This program is free software under the GPL (>=v2)
13  # Read the file COPYING coming with this package for details.  # Read the file COPYING coming with this package for details.
14    
15  """Lohn/Gehaltsrechner f�r das Jahr 2005"""  """Lohn/Gehaltsrechner f�r das Jahr 2008"""
16    
17  __version__ = "$Revision$"  __version__ = "$Revision$"
18  # $Source$  # $Source$
19                    
20  _release_version = "0.1alpha"  _release_version = "0.%s" % __version__[11:-2]
21    
22  import LST2005  import LST2008
23  from Tkinter import *  from Tkinter import *
24    
25  class Lohnrechner(LST2005.LStRechner2005):  class Lohnrechner(LST2008.LStRechner2008):
26    
27      def __init__(self, root):      def __init__(self, root):
28          LST2005.LStRechner2005.__init__(self)          LST2008.LStRechner2008.__init__(self)
29    
30          root.title("Lohnrechner 2005 - v%s" % _release_version)          # Land, Kirchensteuersatz, Pflegeversicherung AG-Anteil
31            self.laender = [("Baden-W�rttemberg", 8, 0.0085, 5300),
32                            ("Bayern", 8, 0.0085, 5300),
33                            ("Berlin (ost)", 9, 0.0085, 4500),
34                            ("Berlin (west)", 9, 0.0085, 5300),
35                            ("Brandenburg", 9, 0.0085, 4500),
36                            ("Bremen", 9, 0.0085, 5300),
37                            ("Bremerhaven", 9, 0.0085, 5300),
38                            ("Hamburg", 9, 0.0085, 5300),
39                            ("Hessen", 9, 0.0085, 5300),
40                            ("Mecklenburg-Vorpommern", 9, 0.0085, 4500),
41                            ("Niedersachsen" ,9, 0.0085, 5300),
42                            ("Nordrhein-Westfalen", 9, 0.0085, 5300),
43                            ("Rheinland-Pfalz", 9, 0.0085, 5300),
44                            ("Saarland", 9, 0.0085, 5300),
45                            ("Sachsen", 9, 0.0135, 4500),
46                            ("Sachsen-Anhalt", 9, 0.0085, 4500),
47                            ("Schleswig-Holstein", 9, 0.0085, 5300),
48                            ("Th�ringen", 9, 0.0085, 4500)]
49            
50            self.root = root
51    
52            self.root.title("Lohnrechner 2008 - v%s" % _release_version)
53    
54            self.SetupUI()
55            self.UpdateLand()
56            self.InitSozv()
57            self.ResetInput()
58    
59          Label(root, text="Lohn:").grid(row=0, sticky=E)      def SetupUI(self):
60          self.lohn = Entry(root)          self.root.resizable(NO, NO)
61    
62            frame = Frame(self.root)
63            frame.grid(padx=10, pady=10)
64    
65            # Steuern Ein/Ausgabe
66            Label(frame, text="Geburtsjahr:").grid(row=0, sticky=E)
67            self.geb = Entry(frame)
68            self.geb.bind("<Return>", self.NewInput)
69            self.geb.grid(row=0, column=1, sticky=W)
70    
71            Label(frame, text="Lohn (monatlich):").grid(row=1, sticky=E)
72            self.lohn = Entry(frame)
73          self.lohn.bind("<Return>", self.NewInput)          self.lohn.bind("<Return>", self.NewInput)
74          self.lohn.grid(row=0, column=1, sticky=W)          self.lohn.grid(row=1, column=1, sticky=W)
75    
76          Label(root, text="Steuerklasse:").grid(row=1, sticky=E)          sonstbezlabel = Label(frame, text="Sonstige Bez�ge:")
77          self.stkl = StringVar()          self.sonstbez = Entry(frame)
78          stklframe = Frame(root)          self.sonstbez.bind("<Return>", self.NewInput)
79          stklframe.grid(row=1, column=1, sticky=W)          # Sonstige Bezuege bisher nur unter Randbedingungen:
80          for text, val in [("I", "1"),          # - Einmalig im Kalenderjahr
81                            ("II", "2"),          # - Keine Ber�cksichtigung bei der Berechnung Sozialbeitr�ge
82                            ("III", "3"),          # Daher per Vorgabe "versteckt", bei Bedarf einfuegen:
83                            ("IV", "4"),          # sonstbezlabel.grid(row=2, sticky=E)
84                            ("V", "5"),          # self.sonstbez.grid(row=2, column=1, sticky=W)
85                            ("VI", "6")]:          
86            Label(frame, text="Steuerklasse:").grid(row=3, sticky=E)
87            self.stkl = IntVar()
88            stklframe = Frame(frame)
89            stklframe.grid(row=3, column=1, sticky=W)
90            for text, val in [("I", 1),
91                              ("II", 2),
92                              ("III", 3),
93                              ("IV", 4),
94                              ("V", 5),
95                              ("VI", 6)]:
96              stklradio = Radiobutton(stklframe, text=text, value=val,              stklradio = Radiobutton(stklframe, text=text, value=val,
97                                      indicatoron=0, command=self.CalcOutput,                                      indicatoron=0, command=self.NewInput,
98                                      variable=self.stkl)                                      variable=self.stkl)
99              if text == "I":              if text == "I":
100                  stklradio.select()                  stklradio.select()
101              stklradio.pack(side=LEFT)              stklradio.pack(side=LEFT)
102    
103          Label(root, text="Kirchensteuer (%):").grid(row=2, sticky=E)          Label(frame, text="Kirchensteuer:").grid(row=4, sticky=E)
104          self.kirche = Entry(root)          self.kirche = IntVar()
105          self.kirche.bind("<Return>", self.NewInput)          Checkbutton(frame, onvalue=1, offvalue=0, command=self.NewInput,
106          self.kirche.grid(row=2, column=1, sticky=W)                      variable=self.kirche).grid(row=4, column=1,sticky=W)
107    
108          self.ResetInput()          Label(frame, text="Kinderfreibetrag:").grid(row=5, sticky=E)
109            self.kfb = Entry(frame)
110          Label(root, text="Lohnsteuer:").grid(row=0, column=2, sticky=E)          self.kfb.bind("<Return>", self.NewInput)
111          self.lst = Entry(root)          self.kfb.grid(row=5, column=1, sticky=W)
112    
113            Label(frame, text="Kinder:").grid(row=6, sticky=E)
114            self.kinder = IntVar()
115            self.kinderradio = Checkbutton(frame, onvalue=1, offvalue=0,
116                                           command=self.NewInput,
117                                           variable=self.kinder)
118            self.kinderradio.grid(row=6, column=1, sticky=W)
119            
120            Label(frame, text="Bundesland:").grid(row=7, sticky=NE)
121            landframe = Frame(frame)
122            scrollbar = Scrollbar(landframe, orient=VERTICAL)
123            self.landbox = Listbox(landframe, height=4, selectmode=SINGLE,
124                                   yscrollcommand=scrollbar.set)
125            for land in self.laender:
126                self.landbox.insert(END, land[0])
127            self.landbox.select_set(0)
128            self.landbox.bind("<<ListboxSelect>>", self.NewLandSel)
129            self.landbox.pack(side=RIGHT, fill=Y)
130            scrollbar.config(command=self.landbox.yview)
131            scrollbar.pack(side=LEFT, fill=BOTH, expand=1)
132            landframe.grid(row=7, rowspan=4, column=1, sticky=W)
133            
134            Label(frame, text="Lohnsteuer:").grid(row=0, column=2, sticky=E)
135            self.lst = Entry(frame)
136          self.lst.grid(row=0, column=3, sticky=W)          self.lst.grid(row=0, column=3, sticky=W)
137    
138          Label(root, text="Solidarit�tszuschlag:").grid(row=1, column=2, sticky=E)          Label(frame, text="Solidarit�tszuschlag:").grid(row=1, column=2, sticky=E)
139          self.soli = Entry(root)          self.soli = Entry(frame)
140          self.soli.grid(row=1, column=3, sticky=W)          self.soli.grid(row=1, column=3, sticky=W)
141    
142          Label(root, text="Kirchensteuer:").grid(row=2, column=2, sticky=E)          Label(frame, text="Kirchensteuer:").grid(row=2, column=2, sticky=E)
143          self.kirchest = Entry(root)          self.kist = Entry(frame)
144          self.kirchest.grid(row=2, column=3, sticky=W)          self.kist.grid(row=2, column=3, sticky=W)
145    
146          self.calcbutton = Button(root, text="Berechnen", command=self.CalcOutput)          Label(frame, text="Lohn nach Steuern:").grid(row=3, column=2, sticky=E)
147          self.calcbutton.grid(row=3, columnspan=4)          self.netto1 = Entry(frame)
148                    self.netto1.grid(row=3, column=3, sticky=W)
149    
150            # Sozialversicherung Ein/Ausgabe
151            Label(frame, text="Sozialversicherung:").grid(row=11, sticky=E)
152            self.sozv = IntVar()
153            sozvradio = Checkbutton(frame, onvalue=1, offvalue=0,
154                                    command=self.NewInput, variable=self.sozv)
155            sozvradio.select()
156            sozvradio.grid(row=11, column=1, sticky=W)
157    
158            Label(frame, text="Krankenkassenbeitrag:").grid(row=12, sticky=E)
159            self.kvsatz = Entry(frame)
160            self.kvsatz.bind("<Return>", self.NewInput)
161            self.kvsatz.grid(row=12, column=1, sticky=W)
162    
163            Label(frame, text="Krankenkassenzuschlag (0.9%):").grid(row=13, sticky=E)
164            self.kvsoli = IntVar()
165            kvsoliradio = Checkbutton(frame, onvalue=1, offvalue=0,
166                                      command=self.NewInput, variable=self.kvsoli)
167            kvsoliradio.select()
168            kvsoliradio.grid(row=13, column=1, sticky=W)
169    
170    
171            Label(frame, text="Rentenversicherung:").grid(row=4, column=2, sticky=E)
172            self.rv = Entry(frame)
173            self.rv.grid(row=4, column=3, sticky=W)
174    
175            Label(frame, text="Krankenversicherung:").grid(row=5, column=2, sticky=E)
176            self.kv = Entry(frame)
177            self.kv.grid(row=5, column=3, sticky=W)
178    
179            Label(frame, text="Arbeitslosenversicherung:").grid(row=6, column=2,
180                                                                sticky=E)
181            self.av = Entry(frame)
182            self.av.grid(row=6, column=3, sticky=W)
183    
184            Label(frame, text="Pflegeversicherung:").grid(row=7, column=2, sticky=E)
185            self.pv = Entry(frame)
186            self.pv.grid(row=7, column=3, sticky=W)
187    
188            Label(frame, text="Netto Lohn:").grid(row=8, column=2, sticky=E)
189            self.netto2 = Entry(frame)
190            self.netto2.grid(row=8, column=3, sticky=W)
191    
192            # Allgemeine UI Elemente
193            buttons = Frame(frame)
194            buttons.grid(row=10, column=2, rowspan=3, columnspan=2)
195            Button(buttons, text="Quit", command=self.root.quit).pack(side=LEFT)
196            Button(buttons, text="Info", command=self.Info).pack(side=LEFT)
197            Button(buttons, text="Berechnen", command=self.CalcOutput).pack(side=LEFT)
198    
199        def NewInput(self, event=0):
200            # Es ist m�glich alle Eintr�ge in der Listbox zu deselektieren,
201            # es ist aber immer genau ein Eintrag aktuell, darum wird er ggf.
202            # zwangsselektiert:
203            # FIX ME: eigendlich w�re das ein Fall f�r ein custom widget!
204            if len(self.landbox.curselection()) == 0:
205                self.landbox.select_set(self.land)
206            if float(self.kfb.get()) > 0.0:
207                self.kinderradio.select()
208          self.CalcOutput()          self.CalcOutput()
209    
210      def NewInput(self, event):      def UpdateLand(self):
211            self.land = int(self.landbox.curselection()[0])
212    
213        def NewLandSel(self, event=0):
214            self.UpdateLand()
215          self.CalcOutput()          self.CalcOutput()
216    
217      def ResetInput(self):      def ResetInput(self):
218            self.ResetInputGeb()
219          self.ResetInputLohn()          self.ResetInputLohn()
220          self.ResetInputKirche()          self.ResetInputSonstBez()
221            self.ResetInputKfb()
222            self.ResetInputKVsatz()
223            self.NewLandSel()
224    
225        def ResetInputGeb(self):
226            self.geb.delete(0, END)
227            self.geb.insert(0, "1964")
228    
229      def ResetInputLohn(self):      def ResetInputLohn(self):
230          self.lohn.delete(0, END)          self.lohn.delete(0, END)
231          self.lohn.insert(0, "0")          self.lohn.insert(0, "0")
232    
233      def ResetInputKirche(self):      def ResetInputSonstBez(self):
234          self.kirche.delete(0, END)          self.sonstbez.delete(0, END)
235          self.kirche.insert(0, "0")          self.sonstbez.insert(0, "0")
236    
237        def ResetInputKfb(self):
238            self.kfb.delete(0, END)
239            self.kfb.insert(0, "0")
240    
241        def ResetInputKVsatz(self):
242            self.kvsatz.delete(0, END)
243            self.kvsatz.insert(0, "13.8")
244    
245      def InitCalc(self):      def InitCalc(self):
246          try:          try:
# Line 96  class Lohnrechner(LST2005.LStRechner2005 Line 249  class Lohnrechner(LST2005.LStRechner2005
249              self.ResetInputLohn()              self.ResetInputLohn()
250    
251          try:          try:
252              self.SetKirchensteuer(float(self.kirche.get()))              self.SetSonstigeBezuege(float(self.sonstbez.get()))
253          except:          except:
254              self.ResetInputKirche()              self.ResetInputSonstBez()
255                
256          self.SetSteuerklasse(int(self.stkl.get()))          # JRE4: N�tig f�r Sonstige Bez�ge.
257            # Voraussichtlicher Jahresarbeitslohn ohne sonstige Bez�ge und ohne
258            # Verg�tung f�r mehrj�hrige T�tigkeit in Cent (ggf. 0)
259            # lohnrechner berechnet diesen aus dem monatlichen Lohn.
260            try:
261                self.Set_JRE4(round(float(self.lohn.get())*100.0,2)*12)
262            except:
263                pass
264    
265            # JVBEZ: N�tig f�r Sonstige Bez�ge.
266            # lohnrechner ber�cksichtigt keine Versorgungsbez�ge, daher 0.
267            self.Set_JVBEZ(0)
268    
269            try:
270                self.SetGeb(int(self.geb.get()))
271            except:
272                self.ResetInputGeb()
273    
274            try:
275                self.SetKinderfreibetrag(float(self.kfb.get()))
276            except:
277                self.ResetInputKfb()
278    
279            try:
280                self.SetKV(float(self.kvsatz.get()))
281            except:
282                self.ResetInputKVsatz()
283    
284            self.SetSteuerklasse(self.stkl.get())
285            self.SetKirchensteuerProzent(self.kirche.get() *
286                                         self.laender[self.land][1])
287    
288      def CalcOutput(self):      def CalcOutput(self):
289          self.InitCalc()          self.InitCalc()
290          self.Calc()          self.Calc()
291          self.lst.delete(0, END)          self.lst.delete(0, END)
292          self.lst.insert(0, "%.2f" % self.GetLohnsteuer())                  self.lst.insert(0, "%.2f" % self.GetLohnsteuerGesamt())
293          self.soli.delete(0, END)          self.soli.delete(0, END)
294          self.soli.insert(0, "%.2f" % self.GetSoli())                  self.soli.insert(0, "%.2f" % self.GetSoliGesamt())
295          self.kirchest.delete(0, END)          self.kist.delete(0, END)
296          self.kirchest.insert(0, "%.2f" % self.GetKirchensteuer())                  self.kist.insert(0, "%.2f" % self.GetKirchensteuerGesamt())
297            netto1 = self.GetLohn() + self.GetSonstigeBezuege() \
298                     - self.GetLohnsteuerGesamt() \
299                     - self.GetSoliGesamt() - self.GetKirchensteuerGesamt()
300            self.netto1.delete(0, END)
301            self.netto1.insert(0, "%.2f" % netto1)
302            self.rv.delete(0, END)
303            self.rv.insert(0, "%.2f" % self.GetRV())
304            self.pv.delete(0, END)
305            self.pv.insert(0, "%.2f" % self.GetPV())
306            self.av.delete(0, END)
307            self.av.insert(0, "%.2f" % self.GetAV())
308            self.kv.delete(0, END)
309            self.kv.insert(0, "%.2f" % self.GetKV())
310            netto2 = netto1 - self.GetRV() - self.GetAV() \
311                     - self.GetPV() - self.GetKV()
312            self.netto2.delete(0, END)
313            self.netto2.insert(0, "%.2f" % netto2)        
314    
315        def Info(self):
316            infowin = Toplevel(self.root)
317            infowin.title("Info")
318            Label(infowin, text="Lohnrechner 2008 v%s" % _release_version,
319                  font=("Times", 14, "bold italic")).grid(row=0, pady=20)
320            Label(infowin, text=
321                  "Copyright (C) 2005,2006,2007,2008 Intevation GmbH \n\n\
322    Lohnrechner 2008 comes with ABSOLUTELY NO WARRANTY.\n\
323    This is free software, and you are welcome to redistribute it\n\
324    under the terms of the GNU General Public License.\n\
325    For more information about these matters, see the file named COPYING.\n\n\
326    Dieses Programm verwendet LST2008 %s" % LST2008._ModulVersion()).grid(row=1, padx=10)
327            Button(infowin, text="Ok", command=infowin.destroy).grid(row=2, pady=10)
328    
329        #
330        # Funktionen zur Berechnung der Sozialversicherungsbeitr�ge.
331        #
332        # FIX ME: Dieser Teil k�nnte evl. in ein eigenes Modul ausgelagert werden.
333        #
334    
335        def InitSozv(self):
336            self.AVsatz = 0.033 / 2
337            self.RVsatz = 0.199 / 2
338            # PVsatz ist in self.laender definiert!
339            self.PVkinderlose = 0.0025
340            self.BMG1 = 3600
341            # BMG2 f�r RV und ALV ist in self.laender definiert!
342    
343        def SetKV(self, value):
344            assert value >= 0.0 and value <= 100.0, \
345                   "must be in range 0.0-100.0 (Percent)"
346            self.KVsatz = (value / 100.0)
347    
348        def GetAV(self):
349            lohn = self.GetLohnGesamt()
350            BMG2 = self.laender[self.land][3]
351            if lohn > BMG2 : lohn = BMG2
352            return round(self.sozv.get() * self.AVsatz * lohn, 2)
353    
354        def GetRV(self):
355            lohn = self.GetLohnGesamt()
356            BMG2 = self.laender[self.land][3]
357            if lohn > BMG2 : lohn = BMG2
358            return round(self.sozv.get() * self.RVsatz * lohn, 2)
359    
360        def GetPV(self):
361            self.PVsatz = self.laender[self.land][2]
362            lohn = self.GetLohnGesamt()
363            if lohn > self.BMG1 : lohn = self.BMG1
364            PV =  self.PVsatz * lohn
365            if self.kinder.get() == 0 :
366                PV += lohn * self.PVkinderlose
367            return round(self.sozv.get() * PV, 2)
368    
369        def GetKV(self):
370            self.KVsoli = self.kvsoli.get()
371            lohn = self.GetLohnGesamt()
372            if lohn > self.BMG1 : lohn = self.BMG1
373            if self.KVsoli :
374                return round(self.sozv.get() * ((self.KVsatz / 2) + 0.009) * lohn, 2)
375            else :
376                return round(self.sozv.get() * self.KVsatz * lohn / 2, 2)
377        
378    
379  if __name__ == "__main__":  if __name__ == "__main__":
380      root = Tk()      root = Tk()
381      lr = Lohnrechner(root)      lr = Lohnrechner(root)
382      root.mainloop()      root.mainloop()
   

Legend:
Removed from v.12  
changed lines
  Added in v.81

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26