weitere Anpassungen

This commit is contained in:
ViperioN1339 2025-04-28 16:52:18 +02:00
parent dc760febde
commit e358454b5e
6 changed files with 161 additions and 133 deletions

View File

@ -7,6 +7,7 @@
<entry key="ChronoFlow.View/LoginView.axaml" value="ChronoFlow.View/ChronoFlow.View.csproj" /> <entry key="ChronoFlow.View/LoginView.axaml" value="ChronoFlow.View/ChronoFlow.View.csproj" />
<entry key="ChronoFlow.View/LoginWindow.axaml" value="ChronoFlow.View/ChronoFlow.View.csproj" /> <entry key="ChronoFlow.View/LoginWindow.axaml" value="ChronoFlow.View/ChronoFlow.View.csproj" />
<entry key="ChronoFlow.View/MainWindow.axaml" value="ChronoFlow.View/ChronoFlow.View.csproj" /> <entry key="ChronoFlow.View/MainWindow.axaml" value="ChronoFlow.View/ChronoFlow.View.csproj" />
<entry key="ChronoFlow.View/MitarbeiterHinzufuegenView.axaml" value="ChronoFlow.View/ChronoFlow.View.csproj" />
<entry key="ChronoFlow.View/ZeiterfassungView.axaml" value="ChronoFlow.View/ChronoFlow.View.csproj" /> <entry key="ChronoFlow.View/ZeiterfassungView.axaml" value="ChronoFlow.View/ChronoFlow.View.csproj" />
</map> </map>
</option> </option>

View File

@ -1,7 +1,6 @@
// Datei: Controller/LoginController.cs // Datei: Controller/LoginController.cs
using ChronoFlow.Model; using ChronoFlow.Model;
using System.Collections.Generic;
using System.Linq;
namespace ChronoFlow.Controller; namespace ChronoFlow.Controller;

View File

@ -1,38 +1,36 @@
using System.Collections.Generic; using System.Collections.Generic; // Für die List<T>
using ChronoFlow.Model; using ChronoFlow.Model; // Zugriff auf das Zeiteintrag-Modell
using ChronoFlow.Persistence; using ChronoFlow.Persistence; // Zugriff auf die Datenbank-Serviceklasse
namespace ChronoFlow.Controller namespace ChronoFlow.Controller
{ {
/// <summary> // Der Controller ist dafür zuständig, die Kommunikation zwischen der View (Oberfläche)
/// Vermittelt zwischen der View und dem Speichersystem (SQLite) // und der Datenbank (Persistence-Schicht) zu regeln.
/// </summary>
public class ZeiterfassungsController 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;
/// <summary> // Konstruktor: Immer wenn ein ZeiterfassungsController erstellt wird,
/// Konstruktor: Initialisiert die Verbindung zum SQLite-Dienst // wird auch gleich ein SqliteService erstellt/verknüpft
/// </summary>
public ZeiterfassungsController() public ZeiterfassungsController()
{ {
_dbService = new SqliteZeiterfassungsService(); _sqliteService = new SqliteZeiterfassungsService();
} }
/// <summary> // Diese Methode wird aufgerufen, wenn ein neuer Zeiteintrag gespeichert werden soll
/// Speichert einen neuen Zeiteintrag dauerhaft in der SQLite-Datenbank
/// </summary>
public void SpeichereEintrag(Zeiteintrag eintrag) 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);
} }
/// <summary> // Diese Methode lädt alle bisherigen Zeiteinträge aus der Datenbank
/// Lädt alle vorhandenen Einträge aus der Datenbank
/// </summary>
public List<Zeiteintrag> LadeAlleEintraege() public List<Zeiteintrag> LadeAlleEintraege()
{ {
return _dbService.LadeAlleZeiteintraege(); // Holt die Liste der Einträge von der Datenbank und gibt sie zurück
return _sqliteService.LadeAlleZeiteintraege();
} }
} }
} }

View File

@ -1,7 +1,3 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Security.Cryptography;
using Microsoft.Data.Sqlite; using Microsoft.Data.Sqlite;
using ChronoFlow.Model; using ChronoFlow.Model;
@ -9,24 +5,39 @@ namespace ChronoFlow.Persistence
{ {
public class SqliteZeiterfassungsService public class SqliteZeiterfassungsService
{ {
private readonly string _dbPath = "chrono_data_v2.sb"; private readonly string _dbPath;
private bool _dbInitialisiert ;
public SqliteZeiterfassungsService() 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)) if (!File.Exists(_dbPath))
{
Console.WriteLine("📂 Datenbank existiert nicht. Erstelle neue...");
ErstelleDatenbank(); ErstelleDatenbank();
} }
else
{
Console.WriteLine("✅ Datenbankdatei gefunden: " + _dbPath);
}
_dbInitialisiert = true;
ZeigeExistierendeTabellen();
}
private void ErstelleDatenbank() private void ErstelleDatenbank()
{ {
Console.WriteLine("🛠️ ErstelleDatenbank wurde aufgerufen!");
using var connection = new SqliteConnection($"Data Source={_dbPath}"); using var connection = new SqliteConnection($"Data Source={_dbPath}");
connection.Open(); connection.Open();
var cmd1 = connection.CreateCommand(); using (var cmd = connection.CreateCommand())
cmd1.CommandText = @" {
cmd.CommandText = @"
CREATE TABLE IF NOT EXISTS Zeiteintraege ( CREATE TABLE IF NOT EXISTS Zeiteintraege (
Id INTEGER PRIMARY KEY AUTOINCREMENT, Id INTEGER PRIMARY KEY AUTOINCREMENT,
Mitarbeiter TEXT NOT NULL, Mitarbeiter TEXT NOT NULL,
@ -36,11 +47,15 @@ namespace ChronoFlow.Persistence
Kommentar TEXT, Kommentar TEXT,
Erledigt INTEGER, Erledigt INTEGER,
MitarbeiterKommentar TEXT MitarbeiterKommentar TEXT
);"; );
cmd1.ExecuteNonQuery(); ";
cmd.ExecuteNonQuery();
Console.WriteLine("🛠️ Tabelle Zeiteintraege wurde erstellt/überprüft.");
}
var cmd2 = connection.CreateCommand(); using (var cmd = connection.CreateCommand())
cmd2.CommandText = @" {
cmd.CommandText = @"
CREATE TABLE IF NOT EXISTS Benutzer ( CREATE TABLE IF NOT EXISTS Benutzer (
Id INTEGER PRIMARY KEY AUTOINCREMENT, Id INTEGER PRIMARY KEY AUTOINCREMENT,
Username TEXT NOT NULL, Username TEXT NOT NULL,
@ -48,10 +63,32 @@ namespace ChronoFlow.Persistence
Role TEXT NOT NULL, Role TEXT NOT NULL,
Mitarbeiternummer TEXT, Mitarbeiternummer TEXT,
Abteilung TEXT Abteilung TEXT
);"; );
cmd2.ExecuteNonQuery(); ";
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 cmd = connection.CreateCommand();
cmd.CommandText = @"
INSERT INTO Benutzer (Username, Password, Role, Mitarbeiternummer, Abteilung)
VALUES ('admin', 'admin', 'Admin', '0001', 'IT');
";
cmd.ExecuteNonQuery();
Console.WriteLine("✅ Standard-Admin erfolgreich erstellt.");
}
public void SpeichereEintrag(Zeiteintrag eintrag) public void SpeichereEintrag(Zeiteintrag eintrag)
{ {
@ -103,23 +140,7 @@ namespace ChronoFlow.Persistence
return eintraege; return eintraege;
} }
public List<string> LadeAlleMitarbeiterNamen()
{
var namen = new List<string>();
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<User> LadeAlleBenutzer() public List<User> LadeAlleBenutzer()
{ {
var benutzerListe = new List<User>(); var benutzerListe = new List<User>();
@ -146,38 +167,39 @@ namespace ChronoFlow.Persistence
return benutzerListe; return benutzerListe;
} }
public void ErstelleStandardAdmin() private void ZeigeExistierendeTabellen()
{ {
using var connection = new SqliteConnection($"Data Source={_dbPath}"); using var connection = new SqliteConnection($"Data Source={_dbPath}");
connection.Open(); connection.Open();
var cmd = connection.CreateCommand(); var cmd = connection.CreateCommand();
cmd.CommandText = @" cmd.CommandText = "SELECT name FROM sqlite_master WHERE type='table';";
INSERT INTO Benutzer (Username, Password, Role, Mitarbeiternummer, Abteilung)
VALUES ('admin', 'admin', 'Admin', '0001', 'IT');
";
cmd.ExecuteNonQuery(); using var reader = cmd.ExecuteReader();
Console.WriteLine("🗂️ Tabellen in der Datenbank:");
Console.WriteLine("✅ Standard-Admin erfolgreich eingefügt."); while (reader.Read())
{
Console.WriteLine($" ➔ {reader.GetString(0)}");
}
} }
public List<string> LadeAlleBenutzernamen() /// <summary>
/// Prüft, ob ein Benutzername bereits existiert.
/// </summary>
/// <param name="username">Benutzername, der überprüft werden soll</param>
/// <returns>True, wenn Name bereits existiert, sonst False</returns>
public bool BenutzernameExistiert(string username)
{ {
var benutzernamen = new List<string>();
using var connection = new SqliteConnection($"Data Source={_dbPath}"); using var connection = new SqliteConnection($"Data Source={_dbPath}");
connection.Open(); connection.Open();
using var cmd = connection.CreateCommand();//<--- Wir erstellen cmd var cmd = connection.CreateCommand();
cmd.CommandText = "SELECT Username From Benutzer;"; cmd.CommandText = "SELECT COUNT(*) FROM Benutzer WHERE Username = $username";
cmd.Parameters.AddWithValue("$username", username);
using var reader = cmd.ExecuteReader(); var result = Convert.ToInt32(cmd.ExecuteScalar());
while (reader.Read())
{ return result > 0;
benutzernamen.Add(reader.GetString(0));
}
return benutzernamen;
} }
} }

View File

@ -1,7 +1,6 @@
using System.Linq; using System.Linq;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Interactivity; using Avalonia.Interactivity;
using Avalonia.Metadata;
using ChronoFlow.Controller; using ChronoFlow.Controller;
using ChronoFlow.Persistence; using ChronoFlow.Persistence;

View File

@ -16,16 +16,16 @@ namespace ChronoFlow.View
} }
private void SpeichernButton_Click(object? sender, RoutedEventArgs e) private void SpeichernButton_Click(object? sender, RoutedEventArgs e)
{ {
try try
{ {
var service = new SqliteZeiterfassungsService(); var service = new SqliteZeiterfassungsService();
string username = UsernameBox.Text ?? ""; string username = UsernameBox.Text?.Trim() ?? "";
string password = PasswordBox.Text ?? ""; string password = PasswordBox.Text?.Trim() ?? "";
string rolle = (RoleBox.SelectedItem as ComboBoxItem)?.Content?.ToString() ?? ""; string rolle = (RoleBox.SelectedItem as ComboBoxItem)?.Content?.ToString() ?? "";
string mitarbeiternummer = MitarbeiternummerBox.Text ?? ""; string mitarbeiternummer = MitarbeiternummerBox.Text?.Trim() ?? "";
string abteilung = AbteilungBox.Text ?? ""; string abteilung = AbteilungBox.Text?.Trim() ?? "";
if (string.IsNullOrWhiteSpace(username) || string.IsNullOrWhiteSpace(password) || string.IsNullOrWhiteSpace(rolle)) if (string.IsNullOrWhiteSpace(username) || string.IsNullOrWhiteSpace(password) || string.IsNullOrWhiteSpace(rolle))
{ {
@ -35,6 +35,15 @@ namespace ChronoFlow.View
return; return;
} }
// ❗ Hier neue Prüfung, ob Benutzername existiert:
if (service.BenutzernameExistiert(username))
{
FeedbackText.Text = "⚠ Benutzername existiert bereits!";
FeedbackText.Foreground = Brushes.Red;
FeedbackText.IsVisible = true;
return;
}
using var connection = new SqliteConnection("Data Source=chrono_data.sb"); using var connection = new SqliteConnection("Data Source=chrono_data.sb");
connection.Open(); connection.Open();
@ -63,7 +72,7 @@ namespace ChronoFlow.View
Console.WriteLine("❌ Ausnahme beim Speichern:"); Console.WriteLine("❌ Ausnahme beim Speichern:");
Console.WriteLine(ex.ToString()); Console.WriteLine(ex.ToString());
} }
} }
} }
} }