diff --git a/.idea/.idea.ChronoFlow/.idea/avalonia.xml b/.idea/.idea.ChronoFlow/.idea/avalonia.xml index b025fdf..69b9e91 100644 --- a/.idea/.idea.ChronoFlow/.idea/avalonia.xml +++ b/.idea/.idea.ChronoFlow/.idea/avalonia.xml @@ -7,6 +7,7 @@ + diff --git a/ChronoFlow.Controller/LoginController.cs b/ChronoFlow.Controller/LoginController.cs index e10bdb9..c7ab770 100644 --- a/ChronoFlow.Controller/LoginController.cs +++ b/ChronoFlow.Controller/LoginController.cs @@ -1,7 +1,6 @@ // Datei: Controller/LoginController.cs using ChronoFlow.Model; -using System.Collections.Generic; -using System.Linq; + namespace ChronoFlow.Controller; diff --git a/ChronoFlow.Controller/ZeiterfassungsController.cs b/ChronoFlow.Controller/ZeiterfassungsController.cs index 42f4a35..c273543 100644 --- a/ChronoFlow.Controller/ZeiterfassungsController.cs +++ b/ChronoFlow.Controller/ZeiterfassungsController.cs @@ -1,38 +1,36 @@ -using System.Collections.Generic; -using ChronoFlow.Model; -using ChronoFlow.Persistence; +using System.Collections.Generic; // Für die List +using ChronoFlow.Model; // Zugriff auf das Zeiteintrag-Modell +using ChronoFlow.Persistence; // Zugriff auf die Datenbank-Serviceklasse namespace ChronoFlow.Controller { - /// - /// Vermittelt zwischen der View und dem Speichersystem (SQLite) - /// + // Der Controller ist dafür zuständig, die Kommunikation zwischen der View (Oberfläche) + // und der Datenbank (Persistence-Schicht) zu regeln. public class ZeiterfassungsController { - private readonly SqliteZeiterfassungsService _dbService; + // Wir brauchen Zugriff auf den Sqlite-Service, um mit der Datenbank arbeiten zu können + private readonly SqliteZeiterfassungsService _sqliteService; - /// - /// Konstruktor: Initialisiert die Verbindung zum SQLite-Dienst - /// + // Konstruktor: Immer wenn ein ZeiterfassungsController erstellt wird, + // wird auch gleich ein SqliteService erstellt/verknüpft public ZeiterfassungsController() { - _dbService = new SqliteZeiterfassungsService(); + _sqliteService = new SqliteZeiterfassungsService(); } - /// - /// Speichert einen neuen Zeiteintrag dauerhaft in der SQLite-Datenbank - /// + // Diese Methode wird aufgerufen, wenn ein neuer Zeiteintrag gespeichert werden soll public void SpeichereEintrag(Zeiteintrag eintrag) { - _dbService.SpeichereEintrag(eintrag); + // Übergibt den Eintrag direkt an den SQLite-Service, + // der kümmert sich um das Speichern in die Datenbank + _sqliteService.SpeichereEintrag(eintrag); } - /// - /// Lädt alle vorhandenen Einträge aus der Datenbank - /// + // Diese Methode lädt alle bisherigen Zeiteinträge aus der Datenbank public List LadeAlleEintraege() { - return _dbService.LadeAlleZeiteintraege(); + // Holt die Liste der Einträge von der Datenbank und gibt sie zurück + return _sqliteService.LadeAlleZeiteintraege(); } } } \ No newline at end of file diff --git a/ChronoFlow.Persistence/SqliteZeiterfassungsService.cs b/ChronoFlow.Persistence/SqliteZeiterfassungsService.cs index c5147f4..a5f5bfb 100644 --- a/ChronoFlow.Persistence/SqliteZeiterfassungsService.cs +++ b/ChronoFlow.Persistence/SqliteZeiterfassungsService.cs @@ -1,7 +1,3 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Security.Cryptography; using Microsoft.Data.Sqlite; using ChronoFlow.Model; @@ -9,50 +5,91 @@ namespace ChronoFlow.Persistence { public class SqliteZeiterfassungsService { - private readonly string _dbPath = "chrono_data_v2.sb"; + private readonly string _dbPath; + private bool _dbInitialisiert ; public SqliteZeiterfassungsService() { - // Prüfe, ob die DB existiert, sonst erstelle sie + _dbPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "chrono_data.sb"); + InitialisiereDatenbank(); + } + + private void InitialisiereDatenbank() + { if (!File.Exists(_dbPath)) + { + Console.WriteLine("📂 Datenbank existiert nicht. Erstelle neue..."); ErstelleDatenbank(); + } + else + { + Console.WriteLine("✅ Datenbankdatei gefunden: " + _dbPath); + } + + _dbInitialisiert = true; + ZeigeExistierendeTabellen(); } private void ErstelleDatenbank() { - Console.WriteLine("🛠️ ErstelleDatenbank wurde aufgerufen!"); + using var connection = new SqliteConnection($"Data Source={_dbPath}"); + connection.Open(); + + using (var cmd = connection.CreateCommand()) + { + cmd.CommandText = @" + CREATE TABLE IF NOT EXISTS Zeiteintraege ( + Id INTEGER PRIMARY KEY AUTOINCREMENT, + Mitarbeiter TEXT NOT NULL, + Startzeit TEXT NOT NULL, + Endzeit TEXT NOT NULL, + Projekt TEXT, + Kommentar TEXT, + Erledigt INTEGER, + MitarbeiterKommentar TEXT + ); + "; + cmd.ExecuteNonQuery(); + Console.WriteLine("🛠️ Tabelle Zeiteintraege wurde erstellt/überprüft."); + } + + using (var cmd = connection.CreateCommand()) + { + cmd.CommandText = @" + CREATE TABLE IF NOT EXISTS Benutzer ( + Id INTEGER PRIMARY KEY AUTOINCREMENT, + Username TEXT NOT NULL, + Password TEXT NOT NULL, + Role TEXT NOT NULL, + Mitarbeiternummer TEXT, + Abteilung TEXT + ); + "; + cmd.ExecuteNonQuery(); + Console.WriteLine("🛠️ Tabelle Benutzer wurde erstellt/überprüft."); + } + } + + public void ErstelleStandardAdmin() + { + if (!_dbInitialisiert) + { + throw new Exception("❗ Fehler: Datenbank wurde noch nicht initialisiert!"); + } using var connection = new SqliteConnection($"Data Source={_dbPath}"); connection.Open(); - var cmd1 = connection.CreateCommand(); - cmd1.CommandText = @" - CREATE TABLE IF NOT EXISTS Zeiteintraege ( - Id INTEGER PRIMARY KEY AUTOINCREMENT, - Mitarbeiter TEXT NOT NULL, - Startzeit TEXT NOT NULL, - Endzeit TEXT NOT NULL, - Projekt TEXT, - Kommentar TEXT, - Erledigt INTEGER, - MitarbeiterKommentar TEXT - );"; - cmd1.ExecuteNonQuery(); + var cmd = connection.CreateCommand(); + cmd.CommandText = @" + INSERT INTO Benutzer (Username, Password, Role, Mitarbeiternummer, Abteilung) + VALUES ('admin', 'admin', 'Admin', '0001', 'IT'); + "; + cmd.ExecuteNonQuery(); - var cmd2 = connection.CreateCommand(); - cmd2.CommandText = @" - CREATE TABLE IF NOT EXISTS Benutzer ( - Id INTEGER PRIMARY KEY AUTOINCREMENT, - Username TEXT NOT NULL, - Password TEXT NOT NULL, - Role TEXT NOT NULL, - Mitarbeiternummer TEXT, - Abteilung TEXT - );"; - cmd2.ExecuteNonQuery(); + Console.WriteLine("✅ Standard-Admin erfolgreich erstellt."); } - public void SpeichereEintrag(Zeiteintrag eintrag) { using var connection = new SqliteConnection($"Data Source={_dbPath}"); @@ -100,26 +137,10 @@ namespace ChronoFlow.Persistence MitarbeiterKommentar = reader.GetString(7) }); } - + return eintraege; } - public List LadeAlleMitarbeiterNamen() - { - var namen = new List(); - - using var connection = new SqliteConnection($"Data Source={_dbPath}"); - connection.Open(); - - var cmd = connection.CreateCommand(); - cmd.CommandText = "SELECT Username From Benutzer Where Role = 'Mitarbeiter';"; - - using var reader = cmd.ExecuteReader(); - while (reader.Read()) - { - namen.Add(reader.GetString(0)); - } - return namen; - } + public List LadeAlleBenutzer() { var benutzerListe = new List(); @@ -146,39 +167,40 @@ namespace ChronoFlow.Persistence return benutzerListe; } - public void ErstelleStandardAdmin() + private void ZeigeExistierendeTabellen() { using var connection = new SqliteConnection($"Data Source={_dbPath}"); connection.Open(); var cmd = connection.CreateCommand(); - cmd.CommandText = @" - INSERT INTO Benutzer (Username, Password, Role, Mitarbeiternummer, Abteilung) - VALUES ('admin', 'admin', 'Admin', '0001', 'IT'); - "; + cmd.CommandText = "SELECT name FROM sqlite_master WHERE type='table';"; - cmd.ExecuteNonQuery(); - - Console.WriteLine("✅ Standard-Admin erfolgreich eingefügt."); - } - - public List LadeAlleBenutzernamen() - { - var benutzernamen = new List(); - - using var connection = new SqliteConnection($"Data Source={_dbPath}"); - connection.Open(); - - using var cmd = connection.CreateCommand();//<--- Wir erstellen cmd - cmd.CommandText = "SELECT Username From Benutzer;"; - using var reader = cmd.ExecuteReader(); + Console.WriteLine("🗂️ Tabellen in der Datenbank:"); while (reader.Read()) { - benutzernamen.Add(reader.GetString(0)); + Console.WriteLine($" ➔ {reader.GetString(0)}"); } - return benutzernamen; } + /// + /// Prüft, ob ein Benutzername bereits existiert. + /// + /// Benutzername, der überprüft werden soll + /// True, wenn Name bereits existiert, sonst False + public bool BenutzernameExistiert(string username) + { + using var connection = new SqliteConnection($"Data Source={_dbPath}"); + connection.Open(); + + var cmd = connection.CreateCommand(); + cmd.CommandText = "SELECT COUNT(*) FROM Benutzer WHERE Username = $username"; + cmd.Parameters.AddWithValue("$username", username); + + var result = Convert.ToInt32(cmd.ExecuteScalar()); + + return result > 0; + } + } } diff --git a/ChronoFlow.View/LoginWindow.axaml.cs b/ChronoFlow.View/LoginWindow.axaml.cs index 4520a55..3a7ba91 100644 --- a/ChronoFlow.View/LoginWindow.axaml.cs +++ b/ChronoFlow.View/LoginWindow.axaml.cs @@ -1,7 +1,6 @@ using System.Linq; using Avalonia.Controls; using Avalonia.Interactivity; -using Avalonia.Metadata; using ChronoFlow.Controller; using ChronoFlow.Persistence; diff --git a/ChronoFlow.View/MitarbeiterHinzufuegenView.axaml.cs b/ChronoFlow.View/MitarbeiterHinzufuegenView.axaml.cs index 799fdc1..ab1c6b8 100644 --- a/ChronoFlow.View/MitarbeiterHinzufuegenView.axaml.cs +++ b/ChronoFlow.View/MitarbeiterHinzufuegenView.axaml.cs @@ -16,54 +16,63 @@ namespace ChronoFlow.View } private void SpeichernButton_Click(object? sender, RoutedEventArgs e) +{ + try + { + var service = new SqliteZeiterfassungsService(); + + string username = UsernameBox.Text?.Trim() ?? ""; + string password = PasswordBox.Text?.Trim() ?? ""; + string rolle = (RoleBox.SelectedItem as ComboBoxItem)?.Content?.ToString() ?? ""; + string mitarbeiternummer = MitarbeiternummerBox.Text?.Trim() ?? ""; + string abteilung = AbteilungBox.Text?.Trim() ?? ""; + + if (string.IsNullOrWhiteSpace(username) || string.IsNullOrWhiteSpace(password) || string.IsNullOrWhiteSpace(rolle)) { - try - { - var service = new SqliteZeiterfassungsService(); + FeedbackText.Text = "⚠ Bitte alle Pflichtfelder ausfüllen!"; + FeedbackText.Foreground = Brushes.Red; + FeedbackText.IsVisible = true; + return; + } - string username = UsernameBox.Text ?? ""; - string password = PasswordBox.Text ?? ""; - string rolle = (RoleBox.SelectedItem as ComboBoxItem)?.Content?.ToString() ?? ""; - string mitarbeiternummer = MitarbeiternummerBox.Text ?? ""; - string abteilung = AbteilungBox.Text ?? ""; + // ❗ Hier neue Prüfung, ob Benutzername existiert: + if (service.BenutzernameExistiert(username)) + { + FeedbackText.Text = "⚠ Benutzername existiert bereits!"; + FeedbackText.Foreground = Brushes.Red; + FeedbackText.IsVisible = true; + return; + } - if (string.IsNullOrWhiteSpace(username) || string.IsNullOrWhiteSpace(password) || string.IsNullOrWhiteSpace(rolle)) - { - FeedbackText.Text = "⚠ Bitte alle Pflichtfelder ausfüllen!"; - FeedbackText.Foreground = Brushes.Red; - FeedbackText.IsVisible = true; - return; - } + using var connection = new SqliteConnection("Data Source=chrono_data.sb"); + connection.Open(); - using var connection = new SqliteConnection("Data Source=chrono_data.sb"); - connection.Open(); - - var cmd = connection.CreateCommand(); - cmd.CommandText = @" + var cmd = connection.CreateCommand(); + cmd.CommandText = @" INSERT INTO Benutzer (Username, Password, Role, Mitarbeiternummer, Abteilung) VALUES ($Username, $Password, $Role, $Mitarbeiternummer, $Abteilung);"; - cmd.Parameters.AddWithValue("$Username", username); - cmd.Parameters.AddWithValue("$Password", password); - cmd.Parameters.AddWithValue("$Role", rolle); - cmd.Parameters.AddWithValue("$Mitarbeiternummer", mitarbeiternummer); - cmd.Parameters.AddWithValue("$Abteilung", abteilung); - cmd.ExecuteNonQuery(); + cmd.Parameters.AddWithValue("$Username", username); + cmd.Parameters.AddWithValue("$Password", password); + cmd.Parameters.AddWithValue("$Role", rolle); + cmd.Parameters.AddWithValue("$Mitarbeiternummer", mitarbeiternummer); + cmd.Parameters.AddWithValue("$Abteilung", abteilung); + cmd.ExecuteNonQuery(); - FeedbackText.Text = "✅ Mitarbeiter erfolgreich gespeichert."; - FeedbackText.Foreground = Brushes.Green; - FeedbackText.IsVisible = true; - } - catch (Exception ex) - { - FeedbackText.Text = $"❌ Fehler: {ex.Message}"; - FeedbackText.Foreground = Brushes.Red; - FeedbackText.IsVisible = true; + FeedbackText.Text = "✅ Mitarbeiter erfolgreich gespeichert."; + FeedbackText.Foreground = Brushes.Green; + FeedbackText.IsVisible = true; + } + catch (Exception ex) + { + FeedbackText.Text = $"❌ Fehler: {ex.Message}"; + FeedbackText.Foreground = Brushes.Red; + FeedbackText.IsVisible = true; - Console.WriteLine("❌ Ausnahme beim Speichern:"); - Console.WriteLine(ex.ToString()); - } - } + Console.WriteLine("❌ Ausnahme beim Speichern:"); + Console.WriteLine(ex.ToString()); + } +} } }