Hier das Dateiformat von den daten in der TxT.
30.05.2024 , Max Mustermann, Max Mustermann1, Appenzell1, TU/Gu1, 10001, 2001, 3.4, ss
Danke schon vorab für die Bemühungen. Grüsse

import tkinter as tk
from tkinter import ttk, messagebox
from tkcalendar import DateEntry
from datetime import datetime
def remove_empty_lines(file_path):
# Liste zum Speichern der bereinigten Zeilen
cleaned_lines = []
# Daten aus der Datei lesen und leere Zeilen entfernen
with open(file_path, "r") as file:
for line in file:
if line.strip():
cleaned_lines.append(line)
# Bereinigte Daten zurück in die Datei schreiben
with open(file_path, "w") as file:
file.writelines(cleaned_lines)
# Pfad zur Kundenverwaltungsdatei
file_path = "kundenverwaltung.txt"
# Aufruf der Funktion, um leere Zeilen zu entfernen
remove_empty_lines(file_path)
class AddCustomerForm:
def __init__(self, root, on_submit):
self.root = root
self.on_submit = on_submit
self.root.title("Neuen Datensatz hinzufügen")
# Label und Kalender für Nachfassdatum
self.lbl_nachfassdatum = ttk.Label(root, text="Nachfassdatum:")
self.lbl_nachfassdatum.grid(row=0, column=0, padx=5, pady=5)
self.cal_nachfassdatum = DateEntry(root, width=12, background='darkblue', foreground='white', borderwidth=2, locale='de_DE')
self.cal_nachfassdatum.grid(row=0, column=1, padx=5, pady=5)
# Label und Entry für Kunde
self.lbl_kunde = ttk.Label(root, text="Kunde:")
self.lbl_kunde.grid(row=1, column=0, padx=5, pady=5)
self.ent_kunde = ttk.Entry(root)
self.ent_kunde.grid(row=1, column=1, padx=5, pady=5)
# Label und Entry für Kontakt
self.lbl_kontakt = ttk.Label(root, text="Kontakt:")
self.lbl_kontakt.grid(row=2, column=0, padx=5, pady=5)
self.ent_kontakt = ttk.Entry(root)
self.ent_kontakt.grid(row=2, column=1, padx=5, pady=5)
# Label und Dropdown-Liste für Kanton
self.lbl_kanton = ttk.Label(root, text="Kanton:")
self.lbl_kanton.grid(row=3, column=0, padx=5, pady=5)
self.combo_kanton = ttk.Combobox(root, values=["Liechtenstein","Appenzell","Aargau (AG)", "Bern (BE)", "Fribourg / Freiburg (FR)", "Genève / Genf (GE)", "Glarus (GL)", "Graubünden (GR)", "Jura (JU)", "Luzern (LU)", "Neuchâtel / Neuenburg (NE)", "St.Gallen (SG)", "Schaffhausen (SH)", "Schwyz (SZ)", "Solothurn (SO)", "Thurgau (TG)", "Ticino / Tessin (TI)", "Uri (UR)", "Valais / Wallis (VS)", "Vaud / Waadt (VD)", "Zug (ZG)", "Zürich (ZH)"])
self.combo_kanton.grid(row=3, column=1, padx=5, pady=5)
# Label und Dropdown-Liste für Kundenart
self.lbl_kundenart = ttk.Label(root, text="Kundenart:")
self.lbl_kundenart.grid(row=4, column=0, padx=5, pady=5)
self.combo_kundenart = ttk.Combobox(root, values=["Installateur", "Planer", "Architekt", "GU/TU"])
self.combo_kundenart.grid(row=4, column=1, padx=5, pady=5)
# Label und Entry für Umsatz
self.lbl_umsatz = ttk.Label(root, text="Umsatz:")
self.lbl_umsatz.grid(row=5, column=0, padx=5, pady=5)
self.ent_umsatz = ttk.Entry(root)
self.ent_umsatz.grid(row=5, column=1, padx=5, pady=5)
# Label und Entry für Mitarbeiter
self.lbl_mitarbeiter = ttk.Label(root, text="Mitarbeiter:")
self.lbl_mitarbeiter.grid(row=6, column=0, padx=5, pady=5)
self.ent_mitarbeiter = ttk.Entry(root)
self.ent_mitarbeiter.grid(row=6, column=1, padx=5, pady=5)
# Label und Entry für KPI
self.lbl_kpi = ttk.Label(root, text="KPI:")
self.lbl_kpi.grid(row=7, column=0, padx=5, pady=5)
self.ent_kpi = ttk.Entry(root)
self.ent_kpi.grid(row=7, column=1, padx=5, pady=5)
self.ent_kpi.config(state=tk.DISABLED) # KPI-Eingabefeld deaktivieren
# Label und Textfeld für Notizen im Formular
self.lbl_notizen = ttk.Label(root, text="Notizen:")
self.lbl_notizen.grid(row=8, column=0, padx=5, pady=5)
self.txt_notizen = tk.Text(root, height=10, width=60) # Anpassen der Größe auf 10 cm hoch und 10 cm lang
self.txt_notizen.grid(row=8, column=1, padx=5, pady=5)
# Button zum Speichern des Datensatzes
self.btn_submit = ttk.Button(root, text="Speichern", command=self.submit)
self.btn_submit.grid(row=9, column=0, columnspan=2, padx=5, pady=5)
def submit(self):
# Daten aus den Eingabefeldern abrufen
nachfassdatum = self.cal_nachfassdatum.get()
kunde = self.ent_kunde.get()
kontakt = self.ent_kontakt.get()
kanton = self.combo_kanton.get()
kundenart = self.combo_kundenart.get()
umsatz = self.ent_umsatz.get()
mitarbeiter = self.ent_mitarbeiter.get()
notizen = self.txt_notizen.get("1.0", tk.END)
# Überprüfen, ob alle Felder ausgefüllt sind
if nachfassdatum and kunde and kontakt and kanton and kundenart and umsatz and mitarbeiter and notizen:
# Berechne den KPI
kpi = AddCustomerForm.calculate_kpi(umsatz, mitarbeiter)
# Aufrufen der Callback-Funktion mit den eingegebenen Daten und dem berechneten KPI
self.on_submit(nachfassdatum, kunde, kontakt, kanton, kundenart, umsatz, mitarbeiter, kpi, notizen)
# Formular schließen
self.root.destroy()
else:
# Fehlermeldung anzeigen, wenn nicht alle Felder ausgefüllt sind
messagebox.showerror("Fehler", "Bitte füllen Sie alle Felder aus.")
@staticmethod
def calculate_kpi(umsatz, mitarbeiter):
# Skala für Umsatz: 1=CHF 0-50000, 5=400000
umsatz_scale = [(0, 50000), (100000, 150000), (200000, 250000), (300000, 350000), (400000, float('inf'))]
# Skala für Mitarbeiter: 1=0-5 Stück, 5=40 Stück
mitarbeiter_scale = [(0, 5), (10, 15), (20, 25), (30, 35), (40, float('inf'))]
# Standardwerte für Ratings
umsatz_rating = 1
mitarbeiter_rating = 1
# Bestimme die Bewertung für Umsatz
for i, (low, high) in enumerate(umsatz_scale):
if low <= float(umsatz) <= high:
umsatz_rating = i + 1
break
# Bestimme die Bewertung für Mitarbeiter
for i, (low, high) in enumerate(mitarbeiter_scale):
if low <= float(mitarbeiter) <= high:
mitarbeiter_rating = i + 1
break
# Berechne den KPI mit der Gewichtung: 60% Mitarbeiter, 40% Umsatz
kpi = (0.4 * umsatz_rating) + (0.6 * mitarbeiter_rating)
return round(kpi, 2)
def edit_customer(self):
# Funktion zum Bearbeiten ausgewählter Datensätze
selected_items = self.tree.selection()
if len(selected_items) != 1:
messagebox.showerror("Fehler", "Bitte wählen Sie genau einen Datensatz zum Bearbeiten aus.")
return
item = selected_items[0]
values = self.tree.item(item, "values")
# Öffnen des Formulars zum Bearbeiten mit den vorhandenen Werten
form = tk.Toplevel()
edit_customer_form = EditCustomerForm(form, self.update_customer, values)
from tkinter import ttk, messagebox
import tkinter as tk
from tkcalendar import DateEntry
from datetime import datetime
class EditCustomerForm:
def __init__(self, root, on_submit, values):
self.root = root
self.on_submit = on_submit
self.values = values
self.root.title("Kunde bearbeiten")
# Label und Kalender für Nachfassdatum
self.lbl_nachfassdatum = ttk.Label(root, text="Nachfassdatum:")
self.lbl_nachfassdatum.grid(row=0, column=0, padx=5, pady=5)
self.cal_nachfassdatum = DateEntry(root, width=12, background='darkblue', foreground='white', borderwidth=2, locale='de_DE')
self.cal_nachfassdatum.grid(row=0, column=1, padx=5, pady=5)
self.cal_nachfassdatum.set_date(values[0])
# Label und Entry für Kunde
self.lbl_kunde = ttk.Label(root, text="Kunde:")
self.lbl_kunde.grid(row=1, column=0, padx=5, pady=5)
self.ent_kunde = ttk.Entry(root)
self.ent_kunde.grid(row=1, column=1, padx=5, pady=5)
self.ent_kunde.insert(0, values[1])
# Label und Entry für Kontakt
self.lbl_kontakt = ttk.Label(root, text="Kontakt:")
self.lbl_kontakt.grid(row=2, column=0, padx=5, pady=5)
self.ent_kontakt = ttk.Entry(root)
self.ent_kontakt.grid(row=2, column=1, padx=5, pady=5)
self.ent_kontakt.insert(0, values[2])
# Label und Dropdown-Liste für Kanton
self.lbl_kanton = ttk.Label(root, text="Kanton:")
self.lbl_kanton.grid(row=3, column=0, padx=5, pady=5)
self.combo_kanton = ttk.Combobox(root, values=["Aargau (AG)", "Appenzell", "Bern (BE)", "Fribourg / Freiburg (FR)", "Genève / Genf (GE)", "Glarus (GL)", "Graubünden (GR)", "Jura (JU)", "Liechtenstein", "Luzern (LU)", "Neuchâtel / Neuenburg (NE)", "St.Gallen (SG)", "Schaffhausen (SH)", "Schwyz (SZ)", "Solothurn (SO)", "Thurgau (TG)", "Ticino / Tessin (TI)", "Uri (UR)", "Valais / Wallis (VS)", "Vaud / Waadt (VD)", "Zug (ZG)", "Zürich (ZH)"])
self.combo_kanton.grid(row=3, column=1, padx=5, pady=5)
self.combo_kanton.set(values[3])
# Label und Dropdown-Liste für Kundenart
self.lbl_kundenart = ttk.Label(root, text="Kundenart:")
self.lbl_kundenart.grid(row=4, column=0, padx=5, pady=5)
self.combo_kundenart = ttk.Combobox(root, values=["Installateur", "Planer", "Architekt", "GU/TU"])
self.combo_kundenart.grid(row=4, column=1, padx=5, pady=5)
self.combo_kundenart.set(values[4])
# Label und Entry für Umsatz
self.lbl_umsatz = ttk.Label(root, text="Umsatz:")
self.lbl_umsatz.grid(row=5, column=0, padx=5, pady=5)
self.ent_umsatz = ttk.Entry(root)
self.ent_umsatz.grid(row=5, column=1, padx=5, pady=5)
self.ent_umsatz.insert(0, values[5])
# Label und Entry für Mitarbeiter
self.lbl_mitarbeiter = ttk.Label(root, text="Mitarbeiter:")
self.lbl_mitarbeiter.grid(row=6, column=0, padx=5, pady=5)
self.ent_mitarbeiter = ttk.Entry(root)
self.ent_mitarbeiter.grid(row=6, column=1, padx=5, pady=5)
self.ent_mitarbeiter.insert(0, values[6])
# Label und Entry für KPI
self.lbl_kpi = ttk.Label(root, text="KPI:")
self.lbl_kpi.grid(row=7, column=0, padx=5, pady=5)
self.ent_kpi = ttk.Entry(root)
self.ent_kpi.grid(row=7, column=1, padx=5, pady=5)
self.ent_kpi.insert(0, values[7])
self.ent_kpi.config(state=tk.DISABLED) # KPI-Eingabefeld deaktivieren
# Label und Textfeld für Notizen im Formular
self.lbl_notizen = ttk.Label(root, text="Notizen:")
self.lbl_notizen.grid(row=8, column=0, padx=5, pady=5)
self.txt_notizen = tk.Text(root, height=10, width=60) # Anpassen der Größe auf 10 cm hoch und 10 cm lang
self.txt_notizen.grid(row=8, column=1, padx=5, pady=5)
self.txt_notizen.insert(tk.END, values[8])
# Button zum Speichern der Änderungen
self.btn_submit = ttk.Button(root, text="Speichern", command=self.submit)
self.btn_submit.grid(row=9, column=0, columnspan=2, padx=5, pady=5)
# Berechnen und Anzeigen des KPI beim Laden des Formulars
self.calculate_and_display_kpi()
def submit(self):
# Daten aus den Eingabefeldern abrufen
nachfassdatum = self.cal_nachfassdatum.get()
kunde = self.ent_kunde.get()
kontakt = self.ent_kontakt.get()
kanton = self.combo_kanton.get()
kundenart = self.combo_kundenart.get()
umsatz = self.ent_umsatz.get()
mitarbeiter = self.ent_mitarbeiter.get()
notizen = self.txt_notizen.get("1.0", tk.END)
# Überprüfen, ob alle Felder ausgefüllt sind
if nachfassdatum and kunde and kontakt and kanton and kundenart and umsatz and mitarbeiter and notizen:
try:
# Nachfassdatum in das richtige Format konvertieren
nachfassdatum = datetime.strptime(nachfassdatum, "%d.%m.%Y")
# Berechnung des KPI und Aufruf der Callback-Funktion
kpi = self.calculate_kpi(umsatz, mitarbeiter)
# Daten speichern und Fenster schließen
self.on_submit(nachfassdatum, kunde, kontakt, kanton, kundenart, umsatz, mitarbeiter, kpi, notizen)
# Update der Datei 'Kundenverwaltung.txt'
with open('Kundenverwaltung.txt', 'r') as file:
lines = file.readlines()
with open('Kundenverwaltung.txt', 'w') as file:
for line in lines:
if line.startswith(self.values[0]):
line = f"{nachfassdatum.strftime('%d.%m.%y')}, {kunde}, {kontakt}, {kanton}, {kundenart}, {umsatz}, {mitarbeiter}, {kpi}, {notizen}\n"
file.write(line)
self.root.destroy()
except ValueError:
# Fehlermeldung anzeigen, wenn das Nachfassdatum ungültig ist
messagebox.showerror("Fehler", "Bitte wählen Sie ein gültiges Nachfassdatum aus.")
else:
# Fehlermeldung anzeigen, wenn nicht alle Felder ausgefüllt sind
messagebox.showerror("Fehler", "Bitte füllen Sie alle Felder aus.")
def calculate_and_display_kpi(self):
# Berechnung des KPI und Anzeige im Formular
umsatz = self.ent_umsatz.get()
mitarbeiter = self.ent_mitarbeiter.get()
kpi = self.calculate_kpi(umsatz, mitarbeiter)
self.ent_kpi.config(state=tk.NORMAL)
self.ent_kpi.delete(0, tk.END)
self.ent_kpi.insert(0, kpi)
self.ent_kpi.config(state=tk.DISABLED)
def calculate_kpi(self, umsatz, mitarbeiter):
# Berechnung des KPI
# Skala für Umsatz: 1=CHF 0-50000, 5=400000
umsatz_scale = [(0, 50000), (100000, 150000), (200000, 250000), (300000, 350000), (400000, float('inf'))]
# Skala für Mitarbeiter: 1=0-5 Stück, 5=40 Stück
mitarbeiter_scale = [(0, 5), (10, 15), (20, 25), (30, 35), (40, float('inf'))]
# Standardwerte für Ratings
umsatz_rating = 1
mitarbeiter_rating = 1
# Bestimme die Bewertung für Umsatz
for i, (low, high) in enumerate(umsatz_scale):
if low <= float(umsatz) <= high:
umsatz_rating = i + 1
break
# Bestimme die Bewertung für Mitarbeiter
for i, (low, high) in enumerate(mitarbeiter_scale):
if low <= float(mitarbeiter) <= high:
mitarbeiter_rating = i + 1
break
# Berechne den KPI mit der Gewichtung: 60% Mitarbeiter, 40% Umsatz
kpi = (0.4 * umsatz_rating) + (0.6 * mitarbeiter_rating)
return round(kpi, 2)
def submit(self):
# Daten aus den Eingabefeldern abrufen
nachfassdatum = self.cal_nachfassdatum.get()
kunde = self.ent_kunde.get()
kontakt = self.ent_kontakt.get()
kanton = self.combo_kanton.get()
kundenart = self.combo_kundenart.get()
umsatz = self.ent_umsatz.get()
mitarbeiter = self.ent_mitarbeiter.get()
kpi = self.ent_kpi.get()
notizen = self.txt_notizen.get("1.0", tk.END)
# Überprüfen, ob alle Felder ausgefüllt sind
if nachfassdatum and kunde and kontakt and kanton and kundenart and umsatz and mitarbeiter and kpi and notizen:
# Aufrufen der Callback-Funktion mit den eingegebenen Daten
self.on_submit(nachfassdatum, kunde, kontakt, kanton, kundenart, umsatz, mitarbeiter, kpi, notizen)
# Formular schließen
self.root.destroy()
else:
# Fehlermeldung anzeigen, wenn nicht alle Felder ausgefüllt sind
messagebox.showerror("Fehler", "Bitte füllen Sie alle Felder aus.")
class CustomerApp:
def __init__(self, root):
self.root = root
self.root.title("Kundenverwaltung")
# Tabelle erstellen und anpassen
self.tree = ttk.Treeview(root, columns=("Nachfassdatum", "Kunde", "Kontakt", "Kanton", "Kundenart", "Umsatz", "Mitarbeiter", "KPI", "Notizen"), show="headings")
self.tree.heading("Nachfassdatum", text="Nachfassdatum", anchor=tk.W)
self.tree.heading("Kunde", text="Kunde", anchor=tk.W)
self.tree.heading("Kontakt", text="Kontakt", anchor=tk.W)
self.tree.heading("Kanton", text="Kanton", anchor=tk.W)
self.tree.heading("Kundenart", text="Kundenart", anchor=tk.W)
self.tree.heading("Umsatz", text="Umsatz", anchor=tk.W)
self.tree.heading("Mitarbeiter", text="Mitarbeiter", anchor=tk.W)
self.tree.heading("KPI", text="KPI", anchor=tk.W)
self.tree.heading("Notizen", text="Notizen", anchor=tk.W)
total_width = root.winfo_screenwidth() * 0.9 # 90% der Bildschirmbreite
column_widths = [total_width * 0.1] * 8 + [total_width * 0.2] # Breite der Spalten festlegen
column_widths[-1] = total_width * 0.4 # Letzte Spalte (Notizen) breiter machen
for i, column in enumerate(self.tree["columns"]):
self.tree.column(column, width=int(column_widths), minwidth=50)
self.tree.pack(fill="both", expand=True) # Anpassen der Tabelle
# Button zum Hinzufügen eines neuen Datensatzes
self.btn_add = ttk.Button(root, text="Hinzufügen", command=self.add_customer)
self.btn_add.pack(pady=5)
# Button zum Löschen von ausgewählten Datensätzen
self.btn_delete = ttk.Button(root, text="Löschen", command=self.delete_customer)
self.btn_delete.pack(pady=5)
# Button zum Bearbeiten ausgewählter Datensätze
self.btn_edit = ttk.Button(root, text="Bearbeiten", command=self.edit_customer)
self.btn_edit.pack(pady=5)
# Daten aus der Textdatei lesen und in die Tabelle einfügen
self.read_data()
def add_customer(self):
# Funktion zum Öffnen des Formulars zum Hinzufügen eines neuen Datensatzes
form = tk.Toplevel()
add_customer_form = AddCustomerForm(form, self.save_customer)
def save_customer(self, nachfassdatum, kunde, kontakt, kanton, kundenart, umsatz, mitarbeiter, kpi, notizen):
# Überprüfen, ob alle Felder ausgefüllt sind
if nachfassdatum and kunde and kontakt and kanton and kundenart and umsatz and mitarbeiter and kpi and notizen:
# Funktion zum Speichern des neuen Datensatzes
with open("kundenverwaltung.txt", "a") as f:
f.write(f"{nachfassdatum}, {kunde}, {kontakt}, {kanton}, {kundenart}, {umsatz}, {mitarbeiter}, {kpi}, {notizen}\n")
# Daten in die Tabelle einfügen
self.tree.insert("", "end", values=(nachfassdatum, kunde, kontakt, kanton, kundenart, umsatz, mitarbeiter, kpi, notizen))
else:
# Fehlermeldung anzeigen, wenn nicht alle Felder ausgefüllt sind
messagebox.showerror("Fehler", "Bitte füllen Sie alle Felder aus.")
def delete_customer(self):
# Funktion zum Löschen ausgewählter Datensätze
selected_items = self.tree.selection()
for item in selected_items:
# Kundenname des ausgewählten Eintrags abrufen
kunde = self.tree.item(item, "values")[1]
# Datensatz aus der Tabelle löschen
self.tree.delete(item)
# Daten aus der Datei entfernen
with open("kundenverwaltung.txt", "r") as f:
lines = f.readlines()
with open("kundenverwaltung.txt", "w") as f:
for line in lines:
# Wenn der Kundenname nicht in der Zeile enthalten ist, schreibe die Zeile zurück in die Datei
if kunde not in line:
f.write(line)
def edit_customer(self):
# Funktion zum Bearbeiten ausgewählter Datensätze
selected_items = self.tree.selection()
if len(selected_items) != 1:
messagebox.showerror("Fehler", "Bitte wählen Sie genau einen Datensatz zum Bearbeiten aus.")
return
item = selected_items[0]
values = tuple(self.tree.item(item, "values"))
# Öffnen des Formulars zum Bearbeiten mit den vorhandenen Werten
form = tk.Toplevel()
edit_customer_form = EditCustomerForm(form, self.update_customer, values)
def update_customer(self, nachfassdatum, kunde, kontakt, kanton, kundenart, umsatz, mitarbeiter, kpi, notizen):
# Funktion zum Aktualisieren der ausgewählten Datensätze
selected_items = self.tree.selection()
for item in selected_items:
# Datensatz in der Tabelle aktualisieren
self.tree.item(item, values=(nachfassdatum, kunde, kontakt, kanton, kundenart, umsatz, mitarbeiter, kpi, notizen))
# Daten in der Datei aktualisieren
old_nachfassdatum = self.tree.item(item, "values")[0]
with open("kundenverwaltung.txt", "r") as f:
lines = f.readlines()
with open("kundenverwaltung.txt", "w") as f:
for line in lines:
if not line.strip().startswith(old_nachfassdatum):
f.write(line)
else:
f.write(f"{nachfassdatum}, {kunde}, {kontakt}, {kanton}, {kundenart}, {umsatz}, {mitarbeiter}, {kpi}, {notizen}\n")
def read_data(self):
# Funktion zum Lesen der Daten aus der Datei und Einfügen in die Tabelle
with open("kundenverwaltung.txt", "r") as f:
for line in f:
data = line.strip().split(", ")
self.tree.insert("", "end", values=data)
# Hauptfunktion zum Starten der Anwendung
def main():
root = tk.Tk()
app = CustomerApp(root)
root.mainloop()
if __name__ == "__main__":
main()