Last active
August 29, 2015 14:07
-
-
Save theRealSuperMario/e03e404276547a0c4b65 to your computer and use it in GitHub Desktop.
für abrechnungen
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="UTF-8"?> | |
<module type="PYTHON_MODULE" version="4"> | |
<component name="NewModuleRootManager"> | |
<content url="file://$MODULE_DIR$" /> | |
<orderEntry type="inheritedJdk" /> | |
<orderEntry type="sourceFolder" forTests="false" /> | |
</component> | |
</module> | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="UTF-8"?> | |
<project version="4"> | |
<component name="Encoding" useUTFGuessing="true" native2AsciiForPropertiesFiles="false" /> | |
</project> | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="UTF-8"?> | |
<project version="4"> | |
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.4.0 (/usr/bin/python3.4)" project-jdk-type="Python SDK" /> | |
</project> | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="UTF-8"?> | |
<project version="4"> | |
<component name="ProjectModuleManager"> | |
<modules> | |
<module fileurl="file://$PROJECT_DIR$/.idea/Abrechnungsapplikation_1.1.iml" filepath="$PROJECT_DIR$/.idea/Abrechnungsapplikation_1.1.iml" /> | |
</modules> | |
</component> | |
</project> | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<component name="DependencyValidationManager"> | |
<state> | |
<option name="SKIP_IMPORT_STATEMENTS" value="false" /> | |
</state> | |
</component> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="UTF-8"?> | |
<project version="4"> | |
<component name="VcsDirectoryMappings"> | |
<mapping directory="" vcs="" /> | |
</component> | |
</project> | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="UTF-8"?> | |
<project version="4"> | |
<component name="ChangeListManager"> | |
<option name="TRACKING_ENABLED" value="true" /> | |
<option name="SHOW_DIALOG" value="false" /> | |
<option name="HIGHLIGHT_CONFLICTS" value="true" /> | |
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" /> | |
<option name="LAST_RESOLUTION" value="IGNORE" /> | |
</component> | |
<component name="ChangesViewManager" flattened_view="true" show_ignored="false" /> | |
<component name="CreatePatchCommitExecutor"> | |
<option name="PATCH_PATH" value="" /> | |
</component> | |
<component name="DaemonCodeAnalyzer"> | |
<disable_hints /> | |
</component> | |
<component name="ProjectLevelVcsManager" settingsEditedManually="false"> | |
<OptionsSetting value="true" id="Add" /> | |
<OptionsSetting value="true" id="Remove" /> | |
<OptionsSetting value="true" id="Checkout" /> | |
<OptionsSetting value="true" id="Update" /> | |
<OptionsSetting value="true" id="Status" /> | |
<OptionsSetting value="true" id="Edit" /> | |
<ConfirmationsSetting value="0" id="Add" /> | |
<ConfirmationsSetting value="0" id="Remove" /> | |
</component> | |
<component name="ProjectReloadState"> | |
<option name="STATE" value="0" /> | |
</component> | |
<component name="RunManager"> | |
<list size="0" /> | |
</component> | |
<component name="ShelveChangesManager" show_recycled="false" /> | |
<component name="TaskManager"> | |
<task active="true" id="Default" summary="Default task"> | |
<created>1406873166190</created> | |
<updated>1406873166190</updated> | |
</task> | |
<servers /> | |
</component> | |
<component name="VcsContentAnnotationSettings"> | |
<option name="myLimit" value="2678400000" /> | |
</component> | |
<component name="VcsManagerConfiguration"> | |
<option name="myTodoPanelSettings"> | |
<TodoPanelSettings /> | |
</option> | |
</component> | |
<component name="XDebuggerManager"> | |
<breakpoint-manager /> | |
</component> | |
</project> | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
__author__ = 'sandro' | |
from tkinter import * | |
import functools | |
import sqlite3 | |
from AusgabenBenutzer import * | |
import datetime | |
import time | |
class AbrechnungsKlasse: | |
def __init__(self, buttonFrame, AusgabenBenutzerFrame, newExpenseFrame, userlistbox, commentlistbox, userDataBasePath): | |
self.buttonFrame = buttonFrame | |
self.ausgabenBenutzerFrame = AusgabenBenutzerFrame | |
self.newExpenseFrame = newExpenseFrame | |
self.datenbankPfad = userDataBasePath | |
self.historylistbox = commentlistbox | |
self.quantityVar = IntVar() | |
self.isEqual = BooleanVar() | |
self.userEntryVar = StringVar() | |
self.userlabelVar = StringVar() | |
self.amountVar = StringVar() | |
self.expenseLabelVar = StringVar() | |
self.commentVar = StringVar() | |
self.userlistbox = userlistbox | |
userlistbox.bind('<Delete>', self.deleteUserButtonEvent) | |
## Buttons and entries | |
self.newExpenseButton = Button(self.buttonFrame, text = "new Expense", command = self.newExpense) | |
self.refreshButton = Button(self.buttonFrame, text = "refresh", command = self.refresh) | |
self.addUserButton = Button(self.buttonFrame, text = "addUser", command = self.addUser) | |
deleteUserButton = Button(self.buttonFrame, text = "deleteUser", command = self.deleteUser) | |
self.commitButton = Button(self.newExpenseFrame, text = "commit", command = self.commitExpense) | |
self.quantityCheckButton = Checkbutton(self.newExpenseFrame, text = "equalShare?", | |
onvalue = True, offvalue = False, variable = self.isEqual, | |
command = self.toggleEqualShare) | |
userinfoLabel = Label(self.buttonFrame, textvariable = self.userlabelVar) | |
self.amountLabel = Label(self.newExpenseFrame, textvariable = self.amountVar) | |
self.expenseLabel = Label(self.newExpenseFrame, textvariable = self.expenseLabelVar) | |
userEntry = Entry(self.buttonFrame, textvariable = self.userEntryVar) | |
userEntry.bind('<Return>', self.addUserButtonEvent) | |
self.quantitySpinbox = Spinbox(self.newExpenseFrame, from_ = 1, to = 500, textvariable = self.quantityVar) | |
self.commentEntry = Entry(self.newExpenseFrame, textvariable = self.commentVar) | |
self.commentEntry.bind('<FocusIn>', functools.partial(self.removeTextOnFocus, entryVar = self.commentVar)) | |
self.commentEntry.bind('<FocusOut>', self.autoCompleteOnFocusOut) | |
#Pack Buttons and entriees | |
self.refreshButton.pack(side = TOP, fill = X) | |
self.newExpenseButton.pack(side = TOP, fill = X) | |
deleteUserButton.pack(side = TOP, fill = X) | |
self.addUserButton.pack(side = TOP, fill = X) | |
userEntry.pack(side = TOP, fill = X) | |
userinfoLabel.pack(side = TOP, fill = X) | |
#Database setup | |
self.UserDataBase = sqlite3.connect(userDataBasePath) | |
self.usercursor = self.UserDataBase.cursor() | |
self.usercursor.execute("""CREATE TABLE IF NOT EXISTS users(name TEXT, kontostand REAL)""") | |
self.usercursor.execute("""CREATE TABLE IF NOT EXISTS history(datum TEXT, datum_nr INTEGER, | |
kommentar TEXT, actions TEXT, sum REAL)""") | |
self.refresh() | |
def newExpense(self): | |
self.expenseLabel.pack(side = LEFT, fill =X) | |
self.expenseLabelVar.set("processing") | |
self.amountVar.set("Die Summe wird" + "\n" + " automatisch errechnet") | |
selectedUsers = self.userlistbox.curselection() | |
for index in selectedUsers: | |
ausgabenBenutzer = AusgabenBenutzer(self.ausgabenBenutzerFrame, | |
str.split(self.userlistbox.get(index))[0], not self.isEqual.get()) | |
ausgabenBenutzer.pack() | |
ausgabenBenutzer.amountentryvar.trace("w", lambda name, index, mode, sv=ausgabenBenutzer.amountentryvar : self.traceAusgabenBenutzerVar(sv)) | |
self.expenseLabelVar.set("") | |
#pack all widgets because they are yet packed | |
self.amountLabel.pack(side = LEFT, fill =X) | |
self.commentEntry.pack(side = LEFT, fill =X) | |
self.commitButton.pack(side = LEFT, fill =X) | |
self.quantityCheckButton.pack(side = LEFT, fill = X) | |
self.quantitySpinbox.pack(side = LEFT, fill = X) | |
self.expenseLabelVar.set("") | |
def refresh(self): | |
for child in self.ausgabenBenutzerFrame.winfo_children(): | |
child.destroy() | |
self.usercursor.execute("SELECT * FROM users") | |
self.userlistbox.delete(0, END) | |
for row in self.usercursor: | |
self.userlistbox.insert(END, row[0] + " " + str(row[1])) | |
for child in self.newExpenseFrame.winfo_children(): | |
child.pack_forget() | |
self.userlabelVar.set("neuen Benutzer eingeben") | |
self.commentVar.set("Kommentar") | |
self.loadHistory() | |
def addUserButtonEvent(self, event): | |
self.addUser() | |
def addUser(self): | |
newUser = self.userEntryVar.get().replace(" ", "_") | |
if newUser == "": | |
self.userlabelVar.set("bitte einen Namen eingeben") | |
else: | |
self.userlabelVar.set("Processing") | |
newUser = self.userEntryVar.get().replace(" ", "_") | |
self.usercursor.execute("SELECT * FROM users WHERE name=(?)", (newUser,)) | |
if self.usercursor.fetchone() == None: | |
werte = (newUser, 0) | |
sql = "INSERT INTO users VALUES (?, ?)" | |
self.usercursor.execute(sql, werte) | |
self.UserDataBase.commit() | |
self.userlistbox.insert(END, newUser) | |
self.userlabelVar.set("benutzer Hinzugefügt") | |
self.userEntryVar.set("") | |
else : | |
self.userlabelVar.set("Name bereits vorhanden") | |
def deleteUserButtonEvent(self, event): | |
self.deleteUser() | |
def deleteUser(self): | |
self.userlabelVar.set("processing") | |
self.buttonFrame.update() | |
selectedUsers = self.userlistbox.curselection() | |
for index in selectedUsers: | |
self.usercursor.execute("DELETE FROM users WHERE name=(?)", (str.split(self.userlistbox.get(index))[0],)) | |
self.UserDataBase.commit() | |
self.refresh() | |
def commitExpense(self): | |
if self.isEqual.get(): | |
self.commitEqualExpense() | |
else: | |
self.commitInEqualExpense() | |
def commitInEqualExpense(self): | |
sum = float(self.amountVar.get()) ##sum of the Expense | |
self.expenseLabelVar.set("processing") | |
self.newExpenseFrame.update() | |
quantitySum = 0 | |
userlist = list() | |
amountlist = list() | |
for child in self.ausgabenBenutzerFrame.winfo_children(): | |
quantitySum += child.getQuantity() | |
if quantitySum == self.quantityVar.get(): | |
pricePerUnit = sum/self.quantityVar.get() ##price per Unit | |
for child in self.ausgabenBenutzerFrame.winfo_children(): | |
userlist.append(child.getName()) | |
individual_amount = child.getQuantity() * pricePerUnit ## How moch did child consume | |
d_kontostand = child.getAmount() - individual_amount ## how much of the consumed did he pay | |
# wenn d_kontostand < 0, hat die Person zu wenig gezahlt und muss noch zahlen | |
# wenn d_kontostand > 0, hat die Person zu viel gezahlt und bekommt Geld raus | |
# d_kontostand ist also quasi ein Maß für Schulden | |
amountlist.append(str(d_kontostand)) | |
self.usercursor.execute("SELECT kontostand FROM users WHERE name = (?)", (child.getName(),)) | |
row = self.usercursor.fetchone() | |
alterKontostand = row[0] | |
self.usercursor.execute("UPDATE users SET kontostand = (?) WHERE name = (?)", | |
(round(alterKontostand + d_kontostand, 2), child.getName())) | |
self.UserDataBase.commit() | |
## add expense to expense History | |
self.historylistbox.insert(END, | |
time.strftime("%d.%m.%Y") + " - " + self.commentVar.get() + " - " + str(sum)) | |
self.addExpenseToHistory(kommentar = self.commentVar.get(), userlist = userlist, amountlist=amountlist, sum = sum) | |
self.refresh() | |
self.expenseLabelVar.set("Done!") | |
self.expenseLabel.pack() | |
def commitEqualExpense(self): | |
self.expenseLabelVar.set("processing") | |
self.newExpenseFrame.update() | |
sum = float(self.amountVar.get()) | |
teilerSumme = sum/len(self.ausgabenBenutzerFrame.children.values()) | |
userlist = list() | |
amountlist = list() | |
for child in self.ausgabenBenutzerFrame.winfo_children(): | |
userlist.append(child.getName()) | |
d_kontostand = child.getAmount() - teilerSumme | |
amountlist.append(str(d_kontostand)) | |
# wenn d_kontostand < 0, hat die Person zu wenig gezahlt und muss noch zahlen | |
# wenn d_kontostand > 0, hat die Person zu viel gezahlt und bekommt Geld raus | |
# d_kontostand ist also quasi ein Maß für Schulden | |
self.usercursor.execute("SELECT kontostand FROM users WHERE name = (?)", (child.getName(),)) | |
row = self.usercursor.fetchone() | |
alterKontostand = row[0] | |
self.usercursor.execute("UPDATE users SET kontostand = (?) WHERE name = (?)", (round(alterKontostand + d_kontostand, 2), child.getName())) | |
self.UserDataBase.commit() | |
self.addExpenseToHistory(kommentar = self.commentVar.get(), userlist = userlist, amountlist=amountlist, sum = sum) | |
self.refresh() | |
self.expenseLabelVar.set("Done!") | |
self.expenseLabel.pack() | |
def autoCompleteOnFocusOut(self, event): | |
if len(self.commentVar.get()) == 0: | |
self.commentVar.set("Kommentar") | |
def traceAusgabenBenutzerVar(self, stringvar): | |
value = checkEntryFormat(stringvar.get()) | |
sum = 0 | |
for child in self.ausgabenBenutzerFrame.winfo_children(): | |
sum += child.getAmount() | |
self.amountVar.set(str(sum)) | |
def removeTextOnFocus(self, event, entryVar): | |
entryVar.set("") | |
def clearHistory(self): | |
for i in range(0, self.historylistbox.size()): | |
self.undoHistoryEvent(i) | |
print("cleared all history events") | |
self.refresh() | |
def toggleEqualShare(self): | |
if self.isEqual.get(): | |
for child in self.ausgabenBenutzerFrame.winfo_children(): | |
child.setQuantityInVisible() | |
self.quantitySpinbox.pack_forget() | |
else: | |
for child in self.ausgabenBenutzerFrame.winfo_children(): | |
child.setQuantityVisible() | |
self.quantitySpinbox.pack() | |
def addExpenseToHistory(self, kommentar, userlist, amountlist, sum): | |
datum = time.strftime("%d.%m.%Y") | |
sql = "INSERT INTO history VALUES (?,?,?,?,?)" | |
action = userlist.__getitem__(0)+ " - " + amountlist.__getitem__(0) | |
self.usercursor.execute("SELECT * FROM history WHERE datum = (?)", (datum,)) | |
datum_nr = len(self.usercursor.fetchall()) | |
print(datum_nr) | |
for i in range(1, len(userlist)): | |
action += "--" | |
action += userlist.__getitem__(i)+ " - " + amountlist.__getitem__(i) | |
#action string:Nutzer1-betrag1--nutzer2-betrag2--nutzer3-betrag3--... | |
werte = (datum, datum_nr, kommentar, action, sum) | |
print("action: " + action) | |
listboxtext = datum + "_" + str(datum_nr) + " - " + self.commentVar.get() + " - " + str(sum) | |
## finally insert into listbox and sql database | |
self.usercursor.execute(sql, werte) | |
self.historylistbox.insert(END, listboxtext) | |
self.UserDataBase.commit() | |
def printHistoryEvent(self, datum, datum_nr): | |
self.usercursor.execute("SELECT * FROM history WHERE datum = ? and datum_nr = ?", (datum, datum_nr,)) | |
event = self.usercursor.fetchone() | |
text = "" | |
for i in range(len(event)): | |
text += str(event[i]) | |
return text | |
def viewHistoryDetails(self): | |
selectedIndex = self.historylistbox.curselection()[0] | |
selected = self.historylistbox.get(selectedIndex) | |
split = selected.split(" -- ") | |
datumAndNumber = split[0].split("_") | |
print(datumAndNumber) | |
print(self.printHistoryEvent(datumAndNumber[0], datumAndNumber[1])) | |
def loadHistory(self): | |
self.historylistbox.delete(0, END) | |
self.usercursor.execute("SELECT * FROM history") | |
for row in self.usercursor.fetchall(): | |
self.historylistbox.insert(END, row[0] + "_" + str(row[1]) + " -- " + row[2] + " -- " + str(row[4])) | |
def undoSelectedHistoryEvents(self): | |
indexlist = self.historylistbox.curselection() | |
for index in indexlist: | |
self.undoHistoryEvent(index) | |
self.refresh() | |
def undoHistoryEvent(self, index): | |
split = self.historylistbox.get(index).split(" -- ") | |
datumAndNumber = split[0].split("_") | |
sql = "SELECT actions, sum FROM history WHERE datum = ? and datum_nr = ?" | |
self.usercursor.execute(sql, (datumAndNumber[0], datumAndNumber[1],)) | |
event = self.usercursor.fetchone() | |
print(event) | |
action = event[0] | |
sum = event[1] | |
userAndAmount = action.split("--") | |
print(userAndAmount) | |
for pair in userAndAmount: | |
name = pair.split(" - ")[0] | |
amount = pair.split(" - ")[1] | |
sqlUser = "SELECT kontostand FROM users WHERE name = ?" | |
alterKontostand = self.usercursor.execute(sqlUser, (name,)).fetchone()[0] | |
print(alterKontostand) | |
neuerKontostand = round(alterKontostand - float(amount), 2) | |
print(neuerKontostand) | |
self.usercursor.execute("UPDATE users SET kontostand = ? WHERE name = ?", (neuerKontostand, name,)) | |
self.usercursor.execute("DELETE FROM history WHERE datum = ? and datum_nr = ?", (datumAndNumber[0], datumAndNumber[1],)) | |
self.UserDataBase.commit() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
__author__ = 'sandro' | |
from tkinter import * | |
import functools | |
def checkEntryFormat(string): | |
if string == "" or string == None or float(string) == "": | |
return 0 | |
else: | |
return round(float(string), 2) | |
class AusgabenBenutzer(Frame): | |
def __init__(self, master, name, isQuantityVisible): | |
Frame.__init__(self, master) | |
self.name = name | |
self.amount = float() | |
self.quantity = IntVar() | |
self.isQuantityVisible = isQuantityVisible | |
self.configure(bd = "2", relief = GROOVE) | |
label = Label(self, text=name) | |
label.pack() | |
self.amountentryvar = StringVar() | |
amountEntryField = Entry(self, textvariable = self.amountentryvar) | |
self.quantitySpinbox = Spinbox(self, textvariable = self.quantity, from_ = 0, to = 500) | |
amountEntryField.pack() | |
amountEntryField.bind('<FocusIn>', functools.partial(self.removeTextOnFocus, entryVar = self.amountentryvar)) | |
amountEntryField.bind('<FocusOut>', self.autoCompleteOnFocusOut) | |
if self.isQuantityVisible: | |
self.quantitySpinbox.pack() | |
self.amountentryvar.set("0.0") | |
def getAmount(self): | |
return checkEntryFormat(checkEntryFormat(self.amountentryvar.get())) | |
def getName(self): | |
return self.name | |
def removeTextOnFocus(self, event, entryVar): | |
entryVar.set("") | |
def autoCompleteOnFocusOut(self, event): | |
self.amountentryvar.set(str(checkEntryFormat(self.amountentryvar.get()))) | |
def getQuantity(self): | |
return self.quantity.get() | |
def toggleQuantityVisibility(self): | |
if self.isQuantityVisible: | |
self.quantitySpinbox.pack_forget() | |
else: | |
self.quantitySpinbox.pack() | |
self.isQuantityVisible = not self.isQuantityVisible | |
def setQuantityVisible(self): | |
self.quantitySpinbox.pack() | |
self.isQuantityVisible = True | |
def setQuantityInVisible(self): | |
self.quantitySpinbox.pack_forget() | |
self.isQuantityVisible = False | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
__author__ = 'sandro' | |
from tkinter import * | |
from AbrechnungsKlasse import * | |
class GUI: | |
def __init__(self): | |
mainWindow = Tk() | |
mainWindow.minsize(700, 500) | |
mainWindow.resizable(1, 1) | |
mainWindow.title("Abrechungsapplikation") | |
## insgesamt 10 row [0-7] und 7 Spalten | |
self.mainFrame = Frame(mainWindow) | |
self.mainFrame.pack() | |
buttonFrame = Frame(self.mainFrame) | |
buttonFrame.grid(row=0, rowspan = 6, column = 0) | |
userlistbox = Listbox(self.mainFrame, selectmode = EXTENDED) | |
userlistbox.grid(row = 0, rowspan = 6, column = 1, columnspan = 3) | |
historylistbox = Listbox(self.mainFrame, width = 30, selectmode = EXTENDED) | |
historylistbox.grid(row=0, rowspan=6, column = 4, columnspan = 4) | |
newExpenseFrame = Frame(self.mainFrame) | |
newExpenseFrame.grid(row = 6 , column = 0, columnspan = 8) | |
AusgabenBenutzerFrame = Frame(self.mainFrame) | |
AusgabenBenutzerFrame.grid(row = 7, rowspan = 3, column = 0, columnspan = 4) | |
a = AbrechnungsKlasse(buttonFrame, AusgabenBenutzerFrame, newExpenseFrame, userlistbox, historylistbox, "Benutzerdatenbank.db") | |
menu = Menu(mainWindow) | |
menu.add_command(label = "view History Event", command = a.viewHistoryDetails) | |
menu.add_command(label = "checkout user") | |
menu.add_command(label = "clearHistory", command = a.clearHistory) | |
menu.add_command(label = "undo History Event", command = a.undoSelectedHistoryEvents) | |
mainWindow.config(menu = menu) | |
mainWindow.mainloop() | |
g = GUI() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment