From 996dbadaf1c0470e96d481866f95b542bd389329 Mon Sep 17 00:00:00 2001 From: DaPi Date: Sun, 20 Oct 2024 17:58:26 +0200 Subject: [PATCH] =?UTF-8?q?Settings=20so=20halb=20und=20a=20bissi=20aufger?= =?UTF-8?q?=C3=A4umt=20...?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Jugenddienst Stunden/MauiProgram.cs | 24 +- Jugenddienst Stunden/Models/Auth.cs | 148 ---------- Jugenddienst Stunden/Models/BaseFunc.cs | 180 ++++++++++++ Jugenddienst Stunden/Models/HoursBase.cs | 125 ++++++++ Jugenddienst Stunden/Models/Note.cs | 8 +- Jugenddienst Stunden/Models/Operator.cs | 63 ++-- Jugenddienst Stunden/Models/Stunde.cs | 211 -------------- Jugenddienst Stunden/Models/TokenData.cs | 18 +- Jugenddienst Stunden/Types/Base.cs | 13 - Jugenddienst Stunden/Types/DayTime.cs | 60 ++-- Jugenddienst Stunden/Types/Freistellung.cs | 2 +- Jugenddienst Stunden/Types/Gemeinde.cs | 2 +- Jugenddienst Stunden/Types/Hours.cs | 13 +- Jugenddienst Stunden/Types/NominalDay.cs | 10 +- Jugenddienst Stunden/Types/NominalWeek.cs | 17 +- Jugenddienst Stunden/Types/Projekt.cs | 2 +- Jugenddienst Stunden/Types/Settings.cs | 32 +- Jugenddienst Stunden/Types/TimeDay.cs | 2 +- Jugenddienst Stunden/Types/Timetable.cs | 17 +- Jugenddienst Stunden/Types/TimetableEntry.cs | 19 +- Jugenddienst Stunden/Types/User.cs | 18 +- .../ViewModels/StundeViewModel.cs | 275 +++++++----------- .../ViewModels/StundenViewModel.cs | 221 ++++++-------- Jugenddienst Stunden/Views/LoginPage.xaml.cs | 32 +- Jugenddienst Stunden/Views/StundePage.xaml | 24 +- Jugenddienst Stunden/Views/StundenPage.xaml | 10 +- .../Views/StundenPage.xaml.cs | 92 +++--- 27 files changed, 707 insertions(+), 931 deletions(-) delete mode 100644 Jugenddienst Stunden/Models/Auth.cs create mode 100644 Jugenddienst Stunden/Models/BaseFunc.cs create mode 100644 Jugenddienst Stunden/Models/HoursBase.cs delete mode 100644 Jugenddienst Stunden/Models/Stunde.cs delete mode 100644 Jugenddienst Stunden/Types/Base.cs diff --git a/Jugenddienst Stunden/MauiProgram.cs b/Jugenddienst Stunden/MauiProgram.cs index 9881125..ce56a8f 100644 --- a/Jugenddienst Stunden/MauiProgram.cs +++ b/Jugenddienst Stunden/MauiProgram.cs @@ -17,20 +17,20 @@ public static class MauiProgram { }) .UseBarcodeReader(); - //Preferences.Default.Set("apiKey", "M3xneWlWNG85TmNIcmo1NnpxWkxVYS9JMDBFRlV8aHR0cHM6Ly9zdHVuZGVuLmpkLWxhbmEtdGlzZW5zLml0L2FwcGFwaQ=="); - //Preferences.Default.Set("name", "Default: Lea"); - //Preferences.Default.Set("surname", "Mair"); - //Preferences.Default.Set("EmployeeId", 3); - //Preferences.Default.Set("apiUrl", "https://stunden.jd-lana-tisens.it/appapi"); - #if DEBUG - Preferences.Default.Set("apiKey", "M3xneWlWNG85TmNIcmo1NnpxWkxVYS9JMDBFRlV8aHR0cDovL2hvdXJzLmRhdW5pLm1pbmUubnU6ODEvYXBwYXBp"); - Preferences.Default.Set("name", "Testserver: Lea"); - Preferences.Default.Set("surname", "Mair"); - Preferences.Default.Set("EmployeeId", 3); - Preferences.Default.Set("apiUrl", "http://hours.dauni.mine.nu:81/appapi"); + //Preferences.Default.Set("apiKey", "M3xneWlWNG85TmNIcmo1NnpxWkxVYS9JMDBFRlV8aHR0cDovL2hvdXJzLmRhdW5pLm1pbmUubnU6ODEvYXBwYXBp"); + //Preferences.Default.Set("name", "Testserver: Lea"); + //Preferences.Default.Set("surname", "Mair"); + //Preferences.Default.Set("EmployeeId", 3); + //Preferences.Default.Set("apiUrl", "http://hours.dauni.mine.nu:81/appapi"); - builder.Logging.AddDebug(); + Preferences.Default.Set("apiKey", "MTQxfHNkdFptQkNZTXlPT3ZyMHNBZDl0UnVxNExMRXxodHRwOi8vaG91cnMuZGF1bmkubWluZS5udTo4MS9hcHBhcGk="); + Preferences.Default.Set("name", "Testserver: Isabell"); + Preferences.Default.Set("surname", "Biasi"); + Preferences.Default.Set("EmployeeId", 141); + Preferences.Default.Set("apiUrl", "http://hours.dauni.mine.nu:81/appapi"); + + builder.Logging.AddDebug(); #endif return builder.Build(); diff --git a/Jugenddienst Stunden/Models/Auth.cs b/Jugenddienst Stunden/Models/Auth.cs deleted file mode 100644 index d9079f2..0000000 --- a/Jugenddienst Stunden/Models/Auth.cs +++ /dev/null @@ -1,148 +0,0 @@ -using Jugenddienst_Stunden.Types; -using System.Diagnostics; -using System.Text; -using System.Text.Json; - - -namespace Jugenddienst_Stunden.Models; - -class Auth { - public static async Task GetApiDataWithAuthAsync(string url, string token) { - // Erstellen eines HttpClient-Objekts - using (HttpClient client = new HttpClient() { Timeout = TimeSpan.FromSeconds(15) }) { - - client.DefaultRequestHeaders.Add("Accept", "application/json"); - - // Hinzufügen des Bearer-Tokens zum Authorization-Header - client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token); - - - // Senden der Anfrage und Abrufen der Antwort - using (HttpResponseMessage HttpResponseMessage = await client.GetAsync(url).ConfigureAwait(false)) { - // Überprüfen, ob die Anfrage erfolgreich war - if (HttpResponseMessage.StatusCode == System.Net.HttpStatusCode.OK) { - using (HttpContent HttpContent = HttpResponseMessage.Content) { - // Lesen und Rückgabe der Antwort als String - string responseData = await HttpContent.ReadAsStringAsync(); - return responseData; - } - } - } - - } - return null; - } - - - /// - /// Stundeneintrag speichern - /// - public static async Task SaveItemAsync(string url, string token, DayTime item, bool isNewItem = false) { - //using (HttpClient client = new HttpClient() { Timeout = TimeSpan.FromSeconds(15) }) { - - //Uhrzeiten sollten sinnvolle Werte haben - if (item.TimeSpanVon == item.TimeSpanBis) { - throw new Exception("Beginn und Ende sind gleich"); - } - - if (item.TimeSpanBis < item.TimeSpanVon) { - throw new Exception("Ende ist vor Beginn"); - } - - TimeSpan span = TimeSpan.Zero; - span += item.TimeSpanBis - item.TimeSpanVon; - if (span.Hours > 10) { - //Hier vielleicht eine Abfrage, ob mehr als 10 Stunden gesund sind? - } - - //Gemeinde ist ein Pflichtfeld - if (item.GemeindeAktiv == null) { - throw new Exception("Gemeinde nicht gewählt"); - } - //Projekt ist ein Pflichtfeld - if (item.ProjektAktiv == null) { - throw new Exception("Projekt nicht gewählt"); - } - //Keine Beschreibung - if (string.IsNullOrEmpty(item.description)) { - throw new Exception("Keine Beschreibung"); - } - //try { - HttpClient client = new HttpClient(); - client.DefaultRequestHeaders.Add("Accept", "application/json"); - client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token); - - string json = JsonSerializer.Serialize(item); - StringContent content = new StringContent(json, Encoding.UTF8, "application/json"); - - HttpResponseMessage? response = null; - if (isNewItem) - response = await client.PostAsync(url, content); - else - response = await client.PutAsync(url, content); - - //if (response.IsSuccessStatusCode) - // Debug.WriteLine(@"\tTodoItem successfully saved."); - if (!response.IsSuccessStatusCode) { - throw new Exception("Fehler beim Speichern " + response.Content); - } - //} catch (Exception ex) { - // Debug.WriteLine(@"\tERROR {0}", ex.Message); - //} - //} - } - - public static async Task DeleteItemAsync(string url, string token) { - //using (HttpClient client = new HttpClient() { Timeout = TimeSpan.FromSeconds(15) }) { - - //try { - HttpClient client = new HttpClient(); - client.DefaultRequestHeaders.Add("Accept", "application/json"); - client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token); - - HttpResponseMessage response = await client.DeleteAsync(url); - - if (!response.IsSuccessStatusCode) - throw new Exception("Fehler beim Löschen " + response.Content); - //if (response.IsSuccessStatusCode) - // Debug.WriteLine(@"\tTodoItem successfully deleted."); - //} catch (Exception ex) { - // Debug.WriteLine(@"\tERROR {0}", ex.Message); - //} - //} - } - - public static async Task AuthUserPass(string user, string pass, string url) { - - var values = new Dictionary - { - { "user", user }, - { "pass", pass } - }; - - var content = new FormUrlEncodedContent(values); - - using (HttpClient client = new HttpClient() { Timeout = TimeSpan.FromSeconds(15) }) { - - client.DefaultRequestHeaders.Add("Accept", "application/json"); - - // Senden der Anfrage und Abrufen der Antwort - using (HttpResponseMessage HttpResponseMessage = await client.PostAsync(url, content).ConfigureAwait(false)) { - // Überprüfen, ob die Anfrage erfolgreich war - if (HttpResponseMessage.StatusCode == System.Net.HttpStatusCode.OK) { - using (HttpContent HttpContent = HttpResponseMessage.Content) { - // Lesen und Rückgabe der Antwort als String - - string responseData = await HttpContent.ReadAsStringAsync(); - User userData = System.Text.Json.JsonSerializer.Deserialize(responseData) ?? throw new Exception("Fehler beim Deserialisieren der Daten"); - return userData; - } - } - } - - } - return null; - } - - -} diff --git a/Jugenddienst Stunden/Models/BaseFunc.cs b/Jugenddienst Stunden/Models/BaseFunc.cs new file mode 100644 index 0000000..a949789 --- /dev/null +++ b/Jugenddienst Stunden/Models/BaseFunc.cs @@ -0,0 +1,180 @@ +using Jugenddienst_Stunden.Types; +using Newtonsoft.Json; +using System.Collections.ObjectModel; +using System.Diagnostics; +using System.Text; +using System.Text.Json; + + +namespace Jugenddienst_Stunden.Models; + +internal static class BaseFunc { + + + internal static async Task GetApiDataWithAuthAsync(string url, string token) { + + if (Connectivity.Current.NetworkAccess == NetworkAccess.None) + throw new Exception("Bitte überprüfen Sie Ihre Internetverbindung und versuchen Sie es erneut."); + + if (string.IsNullOrEmpty(token)) + throw new Exception("Kein APIKEY, bitte zuerst Login durchführen"); + + // Erstellen eines HttpClient-Objekts + using (HttpClient client = new HttpClient() { Timeout = TimeSpan.FromSeconds(15) }) { + + client.DefaultRequestHeaders.Add("Accept", "application/json"); + + // Hinzufügen des Bearer-Tokens zum Authorization-Header + client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token); + + // Senden der Anfrage und Abrufen der Antwort + using (HttpResponseMessage HttpResponseMessage = await client.GetAsync(url).ConfigureAwait(false)) { + var byteArray = await HttpResponseMessage.Content.ReadAsByteArrayAsync(); + string responseData = Encoding.UTF8.GetString(byteArray); + using (HttpContent HttpContent = HttpResponseMessage.Content) { + //responseData = await HttpContent.ReadAsStringAsync(); + } + if (HttpResponseMessage.StatusCode == System.Net.HttpStatusCode.OK) { + return responseData; + } else { + var options = new JsonDocumentOptions { + AllowTrailingCommas = true + }; + using (JsonDocument doc = JsonDocument.Parse(responseData, options)) { + JsonElement root = doc.RootElement; + string message = root.GetProperty("message").GetString() ?? throw new Exception("Fehler: 'message' ist null."); + + throw new Exception(message); + } + } + } + } + } + + + + internal static async Task AuthUserPass(string user, string pass, string url) { + + var values = new Dictionary + { + { "user", user }, + { "pass", pass } + }; + + var content = new FormUrlEncodedContent(values); + + using (HttpClient client = new HttpClient() { Timeout = TimeSpan.FromSeconds(15) }) { + + client.DefaultRequestHeaders.Add("Accept", "application/json"); + + // Senden der Anfrage und Abrufen der Antwort + using (HttpResponseMessage HttpResponseMessage = await client.PostAsync(url, content).ConfigureAwait(false)) { + if (!HttpResponseMessage.IsSuccessStatusCode) + throw new Exception("Fehler beim Einloggen " + HttpResponseMessage.Content); + + // Überprüfen, ob die Anfrage erfolgreich war + if (HttpResponseMessage.StatusCode == System.Net.HttpStatusCode.OK) { + using (HttpContent HttpContent = HttpResponseMessage.Content) { + // Lesen und Rückgabe der Antwort als String + + string responseData = await HttpContent.ReadAsStringAsync(); + User userData = System.Text.Json.JsonSerializer.Deserialize(responseData) ?? throw new Exception("Fehler beim Deserialisieren der Daten"); + return userData; + } + } + } + + } + return null; + } + + + + + internal static HoursBase Load(string filename) { + filename = System.IO.Path.Combine(FileSystem.AppDataDirectory, filename); + + if (!File.Exists(filename)) + throw new FileNotFoundException("Unable to find file on local storage.", filename); + + return + new() { + //Filename = Path.GetFileName(filename), + //Text = File.ReadAllText(filename), + Date = File.GetLastWriteTime(filename) + }; + } + + + + /// + /// Stundeneintrag speichern + /// + internal static async Task SaveItemAsync(string url, string token, DayTime item, bool isNewItem = false) { + + + //Uhrzeiten sollten sinnvolle Werte haben + if (item.TimeSpanVon == item.TimeSpanBis) { + throw new Exception("Beginn und Ende sind gleich"); + } + + if (item.TimeSpanBis < item.TimeSpanVon) { + throw new Exception("Ende ist vor Beginn"); + } + + TimeSpan span = TimeSpan.Zero; + span += item.TimeSpanBis - item.TimeSpanVon; + if (span.Hours > 10) { + //Hier vielleicht eine Abfrage, ob mehr als 10 Stunden gesund sind? + //Das müsste aber das ViewModel machen + } + + //Gemeinde ist ein Pflichtfeld + if (item.GemeindeAktiv == null) { + throw new Exception("Gemeinde nicht gewählt"); + } + //Projekt ist ein Pflichtfeld + if (item.ProjektAktiv == null) { + throw new Exception("Projekt nicht gewählt"); + } + //Keine Beschreibung + if (string.IsNullOrEmpty(item.Description)) { + throw new Exception("Keine Beschreibung"); + } + using (HttpClient client = new HttpClient() { Timeout = TimeSpan.FromSeconds(15) }) { + //HttpClient client = new HttpClient(); + client.DefaultRequestHeaders.Add("Accept", "application/json"); + client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token); + + //string json = JsonSerializer.Serialize(item); + string json = JsonConvert.SerializeObject(item); + StringContent content = new StringContent(json, Encoding.UTF8, "application/json"); + + HttpResponseMessage? response = null; + if (isNewItem) + response = await client.PostAsync(url, content); + else + response = await client.PutAsync(url, content); + + if (!response.IsSuccessStatusCode) { + throw new Exception("Fehler beim Speichern " + response.Content); + } + } + + } + + internal static async Task DeleteItemAsync(string url, string token) { + using (HttpClient client = new HttpClient() { Timeout = TimeSpan.FromSeconds(15) }) { + + //HttpClient client = new HttpClient(); + client.DefaultRequestHeaders.Add("Accept", "application/json"); + client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token); + + HttpResponseMessage response = await client.DeleteAsync(url); + + if (!response.IsSuccessStatusCode) + throw new Exception("Fehler beim Löschen " + response.Content); + } + } + +} diff --git a/Jugenddienst Stunden/Models/HoursBase.cs b/Jugenddienst Stunden/Models/HoursBase.cs new file mode 100644 index 0000000..9f62a71 --- /dev/null +++ b/Jugenddienst Stunden/Models/HoursBase.cs @@ -0,0 +1,125 @@ +using Jugenddienst_Stunden.Types; +using Newtonsoft.Json; +using System.Collections.ObjectModel; + +namespace Jugenddienst_Stunden.Models; + +internal class HoursBase { + + public DateTime Date { get; set; } + + public static string apiKey = Preferences.Default.Get("apiKey", ""); + public static int EmployeeId = Preferences.Default.Get("employeeId", 0); + public static string name = Preferences.Default.Get("name", ""); + public static string surname = Preferences.Default.Get("surname", ""); + public static string apiUrl = Preferences.Default.Get("apiUrl", ""); + + internal static TokenData tokendata = new TokenData(apiKey); + + + /// + /// Einstellungen + /// + internal async Task LoadSettings() { + + string data = await BaseFunc.GetApiDataWithAuthAsync(tokendata.Url + "?settings", tokendata.ApiKey); + + Settings _settings = JsonConvert.DeserializeObject(data) ?? throw new Exception("Fehler beim Deserialisieren der Daten"); + + return _settings; + } + + /// + /// Daten laden + /// + internal async Task LoadData() { + + Hours hours = new Hours(); + + var tokendata = new TokenData(apiKey); + + string data = await BaseFunc.GetApiDataWithAuthAsync(tokendata.Url + "?hours", tokendata.ApiKey); + + hours = JsonConvert.DeserializeObject(data) ?? throw new Exception("Fehler beim Deserialisieren der Daten"); + + return hours; + } + + /// + /// Basisdaten: Mitarbeiterdaten, Projekte, Gemeinden, Freistellungen. + /// + internal static async Task LoadBasicData() { + + Hours hours = new Hours(); + + string data = await BaseFunc.GetApiDataWithAuthAsync(tokendata.Url + "?basic", tokendata.ApiKey); + + hours = JsonConvert.DeserializeObject(data) ?? throw new Exception("Fehler beim Deserialisieren der Daten"); + + return hours; + } + + public static async Task LoadOperator(string apiKey) { + + Operator OperatorVar = new Operator(); + + string data = await BaseFunc.GetApiDataWithAuthAsync(tokendata.Url, tokendata.ApiKey); + + OperatorVar = JsonConvert.DeserializeObject(data); + Preferences.Default.Set("name", OperatorVar.name); + Preferences.Default.Set("surname", OperatorVar.surname); + Preferences.Default.Set("apiUrl", tokendata.Url); + + return OperatorVar; + } + + + /// + /// Zeiten eines Tages holen + /// + internal async Task> LoadDay(DateTime date) { + + string data = await BaseFunc.GetApiDataWithAuthAsync(tokendata.Url + "?date=" + date.ToString("yyyy-MM-dd"), tokendata.ApiKey); + + //List daytimes = System.Text.Json.JsonSerializer.Deserialize>(data) ?? throw new Exception("Fehler beim Deserialisieren der Daten"); + List daytimes = JsonConvert.DeserializeObject>(data); + //List daytimes = JsonConvert.DeserializeObject>(data) ?? throw new Exception("Fehler beim Deserialisieren der Daten"); + + return daytimes; + } + + /// + /// Einzelnen Stundeneintrag holen + /// + internal static async Task LoadEntry(int id) { + + string data = await BaseFunc.GetApiDataWithAuthAsync(tokendata.Url + "?id=" + id, tokendata.ApiKey); + + //DayTime hours = Hours.daytime.Find(x => x.id == id); + DayTime hours = JsonConvert.DeserializeObject(data) ?? throw new Exception("Fehler beim Deserialisieren der Daten"); + hours.TimeSpanVon = hours.Begin.ToTimeSpan(); + hours.TimeSpanBis = hours.End.ToTimeSpan(); + + return hours; + } + + /// + /// Eintrag speichern + /// + internal static async Task SaveEntry(DayTime stunde) { //, string begin, string end, string freistellung, string bemerkung) { + + bool isNew = false; + if (stunde.Id == null) + isNew = true; + await BaseFunc.SaveItemAsync(tokendata.Url, tokendata.ApiKey, stunde, isNew); + + return stunde; + } + + /// + /// Eintrag löschen + /// + internal static async Task DeleteEntry(DayTime stunde) { + await BaseFunc.DeleteItemAsync(tokendata.Url + "/entry/" + stunde.Id, tokendata.ApiKey); + } +} diff --git a/Jugenddienst Stunden/Models/Note.cs b/Jugenddienst Stunden/Models/Note.cs index 66bc902..3f7fa70 100644 --- a/Jugenddienst Stunden/Models/Note.cs +++ b/Jugenddienst Stunden/Models/Note.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Jugenddienst_Stunden.Models; +namespace Jugenddienst_Stunden.Models; internal class Note { public string Filename { get; set; } public string Text { get; set; } diff --git a/Jugenddienst Stunden/Models/Operator.cs b/Jugenddienst Stunden/Models/Operator.cs index e0d6486..0b5a9f8 100644 --- a/Jugenddienst Stunden/Models/Operator.cs +++ b/Jugenddienst Stunden/Models/Operator.cs @@ -1,52 +1,23 @@ - -using CommunityToolkit.Mvvm.ComponentModel; -using Jugenddienst_Stunden.ViewModels; +using CommunityToolkit.Mvvm.ComponentModel; using Newtonsoft.Json; -using System.Text; -namespace Jugenddienst_Stunden.Models; -public class Operator : ObservableObject { - public string? id; - public string? name; - public string? surname; - public string? email; - public string? password; - public string? lang; - public string? admin; - public string? aktiv; - public string? department; - public string? department_name; - public string? num; - public string? year; +namespace Jugenddienst_Stunden.Models; +internal class Operator : HoursBase { + public string? id; + public string? name; + public string? surname; + public string? email; + public string? password; + public string? lang; + public string? admin; + public string? aktiv; + public string? department; + public string? department_name; + public string? num; + public string? year; - public event EventHandler? AlertEvent; + public event EventHandler? AlertEvent; - public static async Task LoadData(string apiKey) { - - Operator OperatorVar = new Operator(); - - if (Connectivity.Current.NetworkAccess == NetworkAccess.None) { - await App.Current.MainPage.DisplayAlert("Keine Internetverbindung", - "Bitte überprüfen Sie Ihre Internetverbindung und versuchen Sie es erneut.", - "OK"); - //throw new Exception("Keine Internetverbindung"); - } else { - var tokendata = new TokenData(apiKey); - - //try { - string data = await Auth.GetApiDataWithAuthAsync(tokendata.url, tokendata.apiKey); - if (data == "\"Lalala\"") { - throw new Exception("Problem mit Token"); - } - if (data != "null") { - OperatorVar = JsonConvert.DeserializeObject(data); - Preferences.Default.Set("name", OperatorVar.name); - Preferences.Default.Set("surname", OperatorVar.surname); - Preferences.Default.Set("apiUrl", tokendata.url); - } - - } - return OperatorVar; - } + } diff --git a/Jugenddienst Stunden/Models/Stunde.cs b/Jugenddienst Stunden/Models/Stunde.cs deleted file mode 100644 index 75372cb..0000000 --- a/Jugenddienst Stunden/Models/Stunde.cs +++ /dev/null @@ -1,211 +0,0 @@ -using CommunityToolkit.Mvvm.ComponentModel; -using Newtonsoft.Json; -using Jugenddienst_Stunden.Types; -using System.Collections.ObjectModel; -using Jugenddienst_Stunden.Exceptions; - -namespace Jugenddienst_Stunden.Models; - -internal class Stunde : ObservableObject { - - public DateTime Date { get; set; } - - public static string apiKey = Preferences.Default.Get("apiKey", ""); - public static int EmployeeId = Preferences.Default.Get("employeeId", 0); - public static string name = Preferences.Default.Get("name", ""); - public static string surname = Preferences.Default.Get("surname", ""); - public static string apiUrl = Preferences.Default.Get("apiUrl", ""); - - - - public static async Task LoadData() { - - if (string.IsNullOrEmpty(apiKey)) { - throw new Exception("Kein APIKEY, bitte zuerst Login durchführen"); - } - - Hours hours = new Hours(); - - if (Connectivity.Current.NetworkAccess == NetworkAccess.None) { - throw new Exception("Bitte überprüfen Sie Ihre Internetverbindung und versuchen Sie es erneut."); - } else { - var tokendata = new TokenData(apiKey); - - //string data = await Auth.GetApiDataWithAuthAsync(requestUrl, apiKey); - string? data = await Auth.GetApiDataWithAuthAsync(tokendata.url + "?hours", tokendata.apiKey); - - if (data == "null") { - throw new Exception("Keine Daten erhalten"); - } - if (data == "\"Lalala\"") { - throw new Exception("Problem mit Token"); - } - - if (data == null) { - throw new Exception("Keine Daten erhalten"); - } - hours = JsonConvert.DeserializeObject(data) ?? throw new Exception("Fehler beim Deserialisieren der Daten"); - - } - return hours; - } - - /// - /// Einstellungen - /// - public static async Task LoadSettings() - { - - Settings settings; - - if (Connectivity.Current.NetworkAccess == NetworkAccess.None) - { - throw new Exception("Bitte überprüfen Sie Ihre Internetverbindung und versuchen Sie es erneut."); - } - else - { - var tokendata = new TokenData(apiKey); - - string? data = await Auth.GetApiDataWithAuthAsync(tokendata.url + "?settings", tokendata.apiKey); - - if (data == "null") - { - throw new Exception("Keine Daten erhalten"); - } - if (data == "\"Lalala\"") - { - throw new Exception("Problem mit Token"); - } - if (data == null) - { - throw new Exception("Keine Daten erhalten"); - } - settings = JsonConvert.DeserializeObject(data) ?? throw new Exception("Fehler beim Deserialisieren der Daten"); - - } - return settings; - } - - /// - /// Basisdaten: Mitarbeiterdaten, Projekte, Gemeinden, Freistellungen. - /// - public static async Task LoadBasicData() { - - Hours hours = new Hours(); - - if (Connectivity.Current.NetworkAccess == NetworkAccess.None) { - throw new Exception("Bitte überprüfen Sie Ihre Internetverbindung und versuchen Sie es erneut."); - } else { - var tokendata = new TokenData(apiKey); - - string? data = await Auth.GetApiDataWithAuthAsync(tokendata.url + "?basic", tokendata.apiKey); - - if (data == "null") { - throw new Exception("Keine Daten erhalten"); - } - if (data == "\"Lalala\"") { - throw new Exception("Problem mit Token"); - } - if (data == null) { - throw new Exception("Keine Daten erhalten"); - } - hours = JsonConvert.DeserializeObject(data) ?? throw new Exception("Fehler beim Deserialisieren der Daten"); - - } - return hours; - } - - - /// - /// Zeiten eines Tages holen - /// - public static async Task> LoadDay(DateTime date) { - if (string.IsNullOrEmpty(apiKey)) { - throw new Exception("Kein APIKEY, bitte zuerst Login durchführen"); - } - - if (Connectivity.Current.NetworkAccess == NetworkAccess.None) { - throw new Exception("Bitte überprüfen Sie Ihre Internetverbindung und versuchen Sie es erneut."); - } - - var tokendata = new TokenData(apiKey); - string? data = await Auth.GetApiDataWithAuthAsync(tokendata.url + "?date=" + date.ToString("yyyy-MM-dd"), tokendata.apiKey); - - if (data == "null") { - throw new NoDataException("Keine Daten für " + date.ToString("ddd. dd. MMM") + " erhalten"); - } - if (data == "\"Lalala\"") { - throw new Exception("Problem mit Token"); - } - if (data == null) { - throw new NoDataException("Keine Daten erhalten"); - } - - - ObservableCollection daytimes = System.Text.Json.JsonSerializer.Deserialize>(data) ?? throw new Exception("Fehler beim Deserialisieren der Daten"); - //daytimes = JsonConvert.DeserializeObject>(data); - //List daytimes = JsonConvert.DeserializeObject>(data) ?? throw new Exception("Fehler beim Deserialisieren der Daten"); - - return daytimes; - - } - - /// - /// Einzelnen Stundeneintrag holen - /// - public static async Task LoadEntry(int id) { - - var tokendata = new TokenData(apiKey); - string? data = await Auth.GetApiDataWithAuthAsync(tokendata.url + "?id=" + id, tokendata.apiKey); - - if (data == null) { - throw new Exception("Keine Daten erhalten"); - } - - //DayTime hours = Hours.daytime.Find(x => x.id == id); - DayTime hours = JsonConvert.DeserializeObject(data) ?? throw new Exception("Fehler beim Deserialisieren der Daten"); - hours.TimeSpanVon = hours.begin.ToTimeSpan(); - hours.TimeSpanBis = hours.end.ToTimeSpan(); - - return hours; - } - - - public static Stunde Load(string filename) { - filename = System.IO.Path.Combine(FileSystem.AppDataDirectory, filename); - - if (!File.Exists(filename)) - throw new FileNotFoundException("Unable to find file on local storage.", filename); - - return - new() { - //Filename = Path.GetFileName(filename), - //Text = File.ReadAllText(filename), - Date = File.GetLastWriteTime(filename) - }; - } - - /// - /// Eintrag speichern - /// - public static async Task SaveEntry(DayTime stunde) { //, string begin, string end, string freistellung, string bemerkung) { - - var tokendata = new TokenData(apiKey); - bool isNew = false; - if (stunde.id == null) - isNew = true; - await Auth.SaveItemAsync(tokendata.url, tokendata.apiKey, stunde, isNew); - - return stunde; - } - - /// - /// Eintrag löschen - /// - public static async Task DeleteEntry(DayTime stunde) { - var tokendata = new TokenData(apiKey); - await Auth.DeleteItemAsync(tokendata.url + "/entry/" + stunde.id, tokendata.apiKey); - } - - -} diff --git a/Jugenddienst Stunden/Models/TokenData.cs b/Jugenddienst Stunden/Models/TokenData.cs index 7688128..dfda9d0 100644 --- a/Jugenddienst Stunden/Models/TokenData.cs +++ b/Jugenddienst Stunden/Models/TokenData.cs @@ -3,17 +3,17 @@ namespace Jugenddienst_Stunden.Models; -class TokenData { - public string token { get; set; } - public string apiKey { get; set; } - public string url { get; set; } - public string operator_id { get; set; } +internal class TokenData { + public string Token { get; set; } + public string ApiKey { get; set; } + public string Url { get; set; } + public string Operator_id { get; set; } public TokenData(string ak) { string dat = Encoding.UTF8.GetString(Convert.FromBase64String(ak)); - token = dat.Split('|')[1]; ; - url = dat.Split('|')[2]; ; - operator_id = dat.Split('|')[0]; ; - apiKey = ak; + Token = dat.Split('|')[1]; ; + Url = dat.Split('|')[2]; ; + Operator_id = dat.Split('|')[0]; ; + ApiKey = ak; } } diff --git a/Jugenddienst Stunden/Types/Base.cs b/Jugenddienst Stunden/Types/Base.cs deleted file mode 100644 index e846de4..0000000 --- a/Jugenddienst Stunden/Types/Base.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System.Collections.ObjectModel; - -namespace Jugenddienst_Stunden.Types; -public struct Base { - public Collection? Projekte { get; set; } - public Collection? Gemeinden { get; set; } - public Collection? Freistellungen { get; set; } - public int EmployeeId { get; set; } - - public Hours Hours { get; set; } - public List daytime { get; set; } - -} diff --git a/Jugenddienst Stunden/Types/DayTime.cs b/Jugenddienst Stunden/Types/DayTime.cs index 6151979..ad5775b 100644 --- a/Jugenddienst Stunden/Types/DayTime.cs +++ b/Jugenddienst Stunden/Types/DayTime.cs @@ -1,15 +1,15 @@ -using System.Collections.ObjectModel; +using CommunityToolkit.Mvvm.ComponentModel; +using System.Collections.ObjectModel; namespace Jugenddienst_Stunden.Types; /// /// Represents a day time entry for an employee. /// -public class DayTime -{ +public class DayTime { /// /// ID des Stundeneintrages /// - public int? id { get; set; } + public int? Id { get; set; } /// /// Mitarbeiter-ID @@ -19,92 +19,76 @@ public class DayTime /// /// Der betreffende Tag /// - public DateTime day { get; set; } + public DateTime Day { get; set; } /// /// Der Wochentag /// - public int wday { get; set; } + public int Wday { get; set; } /// /// Arbeitsbeginn /// - public TimeOnly begin { get; set; } + public TimeOnly Begin { get; set; } /// /// Arbeitsende /// - public TimeOnly end { get; set; } + public TimeOnly End { get; set; } /// - /// Beschreibung der Arbeit + /// Beschreibung der Tätigkeit /// - public string description { get; set; } + public string? Description { get; set; } /// /// Freistellung /// - public string? free { get; set; } + public string? Free { get; set; } /// - /// Freisetellung genehmigt? + /// Freistellung genehmigt? /// - public bool? approved { get; set; } + public bool? Approved { get; set; } - /// - /// Sollte nix sein - /// - public int? type { get; set; } /// /// Das gewählte Projekt /// - public int? projekt { get; set; } + public int? Projekt { get; set; } /// /// Die gewählte Gemeinde /// - public int? gemeinde { get; set; } + public int? Gemeinde { get; set; } /// /// Nachtstunden /// - public TimeOnly night { get; set; } + public TimeOnly Night { get; set; } /// /// Summe Arbeitszeit (inklusive Nachstunden mit Faktor) /// - public Dictionary total { get; set; } - public TimeOnly end_print { get; set; } + public Dictionary Total { get; set; } + + public TimeOnly End_print { get; set; } public TimeSpan TimeSpanVon { get; set; } public TimeSpan TimeSpanBis { get; set; } - /// - /// Projekte für die Auswahlliste - /// - public Collection Projekte { get; set; } - - /// - /// Gemeinden für die Auswahlliste - /// - public Collection Gemeinden { get; set; } - public Collection Freistellungen { get; set; } - /// /// Gets the active Gemeinde based on the gemeinde ID. /// - public Gemeinde GemeindeAktiv { get; set; } + public Gemeinde? GemeindeAktiv { get; set; } /// /// Gets the active Projekt based on the projekt ID. /// - public Projekt ProjektAktiv { get; set; } + public Projekt? ProjektAktiv { get; set; } /// /// Gets the active Freistellung based on the Freistellung ID /// - public Freistellung FreistellungAktiv { get; set; } + public Freistellung? FreistellungAktiv { get; set; } - public bool ProjektAktivSet { get; set; } = false; - public bool GemeindeAktivSet { get; set; } = false; } diff --git a/Jugenddienst Stunden/Types/Freistellung.cs b/Jugenddienst Stunden/Types/Freistellung.cs index 3a3cea5..6bc88dc 100644 --- a/Jugenddienst Stunden/Types/Freistellung.cs +++ b/Jugenddienst Stunden/Types/Freistellung.cs @@ -3,6 +3,6 @@ /// Freistellungen: Urlaub, Zeitausgleich, Krankheit, ... /// public class Freistellung { - public string? Id { get; set; } + public string? Id { get; set; } public string? Name { get; set; } } diff --git a/Jugenddienst Stunden/Types/Gemeinde.cs b/Jugenddienst Stunden/Types/Gemeinde.cs index 5a9a8f7..f2cdf1f 100644 --- a/Jugenddienst Stunden/Types/Gemeinde.cs +++ b/Jugenddienst Stunden/Types/Gemeinde.cs @@ -7,7 +7,7 @@ public class Gemeinde { /// /// Eindeutige Id der Gemeinde. /// - public int Id { get; set; } + public int? Id { get; set; } /// /// Name der Gemeinde. diff --git a/Jugenddienst Stunden/Types/Hours.cs b/Jugenddienst Stunden/Types/Hours.cs index 28b2411..2b79c03 100644 --- a/Jugenddienst Stunden/Types/Hours.cs +++ b/Jugenddienst Stunden/Types/Hours.cs @@ -1,19 +1,18 @@  using CommunityToolkit.Mvvm.ComponentModel; -using Newtonsoft.Json; using System.Collections.ObjectModel; namespace Jugenddienst_Stunden.Types; -public class Hours : ObservableObject { - public string? zeit; - public string? nominal; +internal class Hours : ObservableObject { + public string? Zeit; + public string? Nominal; //public Dictionary nominal_day_api; - public List? nominal_day_api; + public List? Nominal_day_api; //public Dictionary nominal_week_api; - public List? nominal_week_api; + public List? Nominal_week_api; //public List time_line; - public string? zeit_total; + public string? Zeit_total; //https://stackoverflow.com/questions/29449641/deserialize-json-when-a-value-can-be-an-object-or-an-empty-array/29450279#29450279 //[JsonConverter(typeof(JsonSingleOrEmptyArrayConverter))] diff --git a/Jugenddienst Stunden/Types/NominalDay.cs b/Jugenddienst Stunden/Types/NominalDay.cs index 0ee9c47..34590b1 100644 --- a/Jugenddienst Stunden/Types/NominalDay.cs +++ b/Jugenddienst Stunden/Types/NominalDay.cs @@ -1,11 +1,5 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Jugenddienst_Stunden.Types; -public class NominalDay { +namespace Jugenddienst_Stunden.Types; +internal class NominalDay { public int day_number; public int month_number; public decimal hours; diff --git a/Jugenddienst Stunden/Types/NominalWeek.cs b/Jugenddienst Stunden/Types/NominalWeek.cs index fc19306..db2747b 100644 --- a/Jugenddienst Stunden/Types/NominalWeek.cs +++ b/Jugenddienst Stunden/Types/NominalWeek.cs @@ -1,13 +1,6 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +namespace Jugenddienst_Stunden.Types; -namespace Jugenddienst_Stunden.Types; - - public class NominalWeek - { - public int week_number; - public decimal hours; - } +internal class NominalWeek { + public int Week_number; + public decimal Hours; +} diff --git a/Jugenddienst Stunden/Types/Projekt.cs b/Jugenddienst Stunden/Types/Projekt.cs index ea4a2ad..c4bdd91 100644 --- a/Jugenddienst Stunden/Types/Projekt.cs +++ b/Jugenddienst Stunden/Types/Projekt.cs @@ -7,7 +7,7 @@ public class Projekt { /// /// Holt oder setzt die eindeutige ID des Projekts. /// - public int Id { get; set; } + public int? Id { get; set; } /// /// Holt oder setzt den Namen des Projekts. diff --git a/Jugenddienst Stunden/Types/Settings.cs b/Jugenddienst Stunden/Types/Settings.cs index 2860de3..1175b87 100644 --- a/Jugenddienst Stunden/Types/Settings.cs +++ b/Jugenddienst Stunden/Types/Settings.cs @@ -1,15 +1,31 @@ -using System.Collections.ObjectModel; - -namespace Jugenddienst_Stunden.Types; +namespace Jugenddienst_Stunden.Types; /// /// Einstellungen /// -public class Settings -{ +public class Settings { + /// + /// Sind Projekte aktiv? + /// public bool ProjektAktivSet { get; set; } + + /// + /// Sind Gemeinden aktiv? + /// public bool GemeindeAktivSet { get; set; } - public Collection Projekte { get; set; } - public Collection Gemeinden { get; set; } - public Collection Freistellungen { get; set; } + + /// + /// Liste der Projekte + /// + public List? Projekte { get; set; } + + /// + /// Liste der Gemeinden + /// + public List? Gemeinden { get; set; } + + /// + /// Liste der Freistellungen + /// + public List? Freistellungen { get; set; } } diff --git a/Jugenddienst Stunden/Types/TimeDay.cs b/Jugenddienst Stunden/Types/TimeDay.cs index 11bb3d5..ccdb79b 100644 --- a/Jugenddienst Stunden/Types/TimeDay.cs +++ b/Jugenddienst Stunden/Types/TimeDay.cs @@ -3,7 +3,7 @@ /// /// Summe der geleisteten Stunden. /// -public struct TimeDay { +internal struct TimeDay { public int Day { get; set; } public decimal Hours { get; set; } } diff --git a/Jugenddienst Stunden/Types/Timetable.cs b/Jugenddienst Stunden/Types/Timetable.cs index 9df3c32..1c8090b 100644 --- a/Jugenddienst Stunden/Types/Timetable.cs +++ b/Jugenddienst Stunden/Types/Timetable.cs @@ -1,13 +1,6 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +namespace Jugenddienst_Stunden.Types; -namespace Jugenddienst_Stunden.Types; - - internal class Timetable - { - public List timetable; - public decimal wochensumme; - } +internal class Timetable { + public List timetable; + public decimal wochensumme; +} diff --git a/Jugenddienst Stunden/Types/TimetableEntry.cs b/Jugenddienst Stunden/Types/TimetableEntry.cs index 0ec05eb..f19853e 100644 --- a/Jugenddienst Stunden/Types/TimetableEntry.cs +++ b/Jugenddienst Stunden/Types/TimetableEntry.cs @@ -1,14 +1,7 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +namespace Jugenddienst_Stunden.Types; -namespace Jugenddienst_Stunden.Types; - - internal class TimetableEntry - { - public List? von; - public List? bis; - public decimal summe { get; set; } - } +internal class TimetableEntry { + public List? Von; + public List? Bis; + public decimal Summe { get; set; } +} diff --git a/Jugenddienst Stunden/Types/User.cs b/Jugenddienst Stunden/Types/User.cs index 271e0fb..b6d03cd 100644 --- a/Jugenddienst Stunden/Types/User.cs +++ b/Jugenddienst Stunden/Types/User.cs @@ -1,13 +1,7 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Jugenddienst_Stunden.Types; -public class User { - public int id { get; set; } - public string name { get; set; } - public string surname { get; set; } - public string token { get; set; } +namespace Jugenddienst_Stunden.Types; +internal class User { + public int Id { get; set; } + public string Name { get; set; } + public string Surname { get; set; } + public string Token { get; set; } } diff --git a/Jugenddienst Stunden/ViewModels/StundeViewModel.cs b/Jugenddienst Stunden/ViewModels/StundeViewModel.cs index ba6f875..9790f59 100644 --- a/Jugenddienst Stunden/ViewModels/StundeViewModel.cs +++ b/Jugenddienst Stunden/ViewModels/StundeViewModel.cs @@ -1,100 +1,68 @@ using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; +using Jugenddienst_Stunden.Models; using Jugenddienst_Stunden.Types; -using System.Collections.ObjectModel; using System.Windows.Input; -using static System.Runtime.InteropServices.JavaScript.JSType; namespace Jugenddienst_Stunden.ViewModels; -internal class StundeViewModel : ObservableObject, IQueryAttributable -{ - - public int id { get; set; } +public class StundeViewModel : ObservableObject, IQueryAttributable { + public int Id { get; set; } + public string Title { get; set; } = "Eintrag bearbeiten"; public string SubTitle { get; set; } = DateTime.Today.ToString("dddd, d. MMMM yyyy"); - private Settings _settings; - public Settings Settings - { - get => _settings; set - { - if (_settings != value) - { - _settings = value; - } - } - } - - private DayTime _stunde; - public DayTime Stunde - { - get => _stunde; - set - { - if (_stunde != value) - { - _stunde = value; - OnPropertyChanged(nameof(Stunde)); - } - } - } - - public string Title { get; set; } = "Eintrag bearbeiten"; + private HoursBase HoursBase = new HoursBase(); + internal Settings Settings = new Settings(); public event EventHandler AlertEvent; public event EventHandler InfoEvent; public event Func> ConfirmEvent; + /// + /// Gemeinden für die Auswahlliste + /// + public List OptionsGemeinde { get; private set; } - public ObservableCollection OptionsGemeinde { get; private set; } - public ObservableCollection OptionsProjekt { get; private set; } - public ObservableCollection OptionsFreistellung { get; private set; } - public ObservableCollection DayTimes { get; set; } + /// + /// Projekte für die Auswahlliste + /// + public List OptionsProjekt { get; private set; } - //private Gemeinde _selectedGemeinde; - public Gemeinde SelectedOptionGemeinde - { - get => _stunde.GemeindeAktiv; - set - { - if (_stunde.GemeindeAktiv != value) - { - //_selectedGemeinde = value; - _stunde.GemeindeAktiv = value; - OnPropertyChanged(nameof(SelectedOptionGemeinde)); - } + /// + /// Freistellungen für die Auswahlliste + /// + public List OptionsFreistellung { get; private set; } + + /// + /// Vorhandene Zeiten anzeigen, wenn neuer Eintrag erstellt wird + /// + public List DayTimes { get; set; } + + private DayTime _dayTime; + /// + /// Aktueller Stundeneintrag + /// + public DayTime DayTime { + get => _dayTime; + set { + if (_dayTime != value) { + _dayTime = value; + + }OnPropertyChanged(nameof(DayTime)); } } - //private Projekt _selectedProjekt; - public Projekt SelectedOptionProjekt - { - get => _stunde.ProjektAktiv; - set - { - if (_stunde.ProjektAktiv != value) - { - //_selectedProjekt = value; - _stunde.ProjektAktiv = value; - OnPropertyChanged(nameof(SelectedOptionProjekt)); - } - } - } - //private Freistellung _selectedFreistellung; - public Freistellung SelectedOptionFreistellung - { - get => _stunde.FreistellungAktiv; - set - { - if (_stunde.FreistellungAktiv != value) - { - _stunde.FreistellungAktiv = value; - OnPropertyChanged(nameof(SelectedOptionFreistellung)); - } - } - } + /// + /// Dürfen Gemeinden verwendet werden? + /// + public bool GemeindeAktivSet { get; set; } + + /// + /// Dürfen Projekte verwendet werden? + /// + public bool ProjektAktivSet { get; set; } @@ -104,156 +72,131 @@ internal class StundeViewModel : ObservableObject, IQueryAttributable //public ICommand LoadDataCommand { get; private set; } - public StundeViewModel() - { - _stunde = new DayTime(); + public StundeViewModel() { + DayTime = new DayTime(); SaveCommand = new AsyncRelayCommand(Save); //DeleteCommand = new AsyncRelayCommand(Delete); DeleteConfirmCommand = new Command(async () => await DeleteConfirm()); - + LoadSettingsAsync(); } - public StundeViewModel(DayTime stunde) - { - _stunde = stunde; + public StundeViewModel(DayTime stunde) { + DayTime = new DayTime(); SaveCommand = new AsyncRelayCommand(Save); DeleteConfirmCommand = new AsyncRelayCommand(DeleteConfirm); + LoadSettingsAsync(); } - private async Task LoadData() - { - try - { - Hours _hours = await Models.Stunde.LoadBasicData(); - OptionsProjekt = new ObservableCollection(_hours.Projekte); - OptionsGemeinde = new ObservableCollection(_hours.Gemeinden); - OptionsFreistellung = new ObservableCollection(_hours.Freistellungen); - OnPropertyChanged(nameof(OptionsGemeinde)); - OnPropertyChanged(nameof(OptionsProjekt)); - OnPropertyChanged(nameof(OptionsFreistellung)); - _stunde.EmployeeId = _hours.EmployeeId; - } - catch (Exception e) - { + private async void LoadSettingsAsync() { + Settings = await HoursBase.LoadSettings(); + + OptionsGemeinde = Settings.Gemeinden; + OptionsProjekt = Settings.Projekte; + OptionsFreistellung = Settings.Freistellungen; + + GemeindeAktivSet = Settings.GemeindeAktivSet; + ProjektAktivSet = Settings.ProjektAktivSet; + + OnPropertyChanged(nameof(OptionsGemeinde)); + OnPropertyChanged(nameof(OptionsFreistellung)); + OnPropertyChanged(nameof(OptionsProjekt)); + + OnPropertyChanged(nameof(GemeindeAktivSet)); + OnPropertyChanged(nameof(ProjektAktivSet)); + + + } + + private async Task LoadData() { + try { + Hours _hours = await Models.HoursBase.LoadBasicData(); + DayTime.EmployeeId = _hours.EmployeeId; + } catch (Exception e) { AlertEvent?.Invoke(this, e.Message); } } - async Task Save() - { + async Task Save() { bool exceptionOccurred = false; - try - { - await Models.Stunde.SaveEntry(_stunde); - } - catch (Exception e) - { + try { + await Models.HoursBase.SaveEntry(DayTime); + } catch (Exception e) { AlertEvent?.Invoke(this, e.Message); exceptionOccurred = true; } - if (!exceptionOccurred) - { - if (_stunde.id != null) - { - await Shell.Current.GoToAsync($"..?saved={_stunde.id}"); - } - else - { - await Shell.Current.GoToAsync($"..?date={_stunde.day.ToString("yyyy-MM-dd")}"); + if (!exceptionOccurred) { + if (DayTime.Id != null) { + await Shell.Current.GoToAsync($"..?saved={DayTime.Id}"); + } else { + await Shell.Current.GoToAsync($"..?date={DayTime.Day.ToString("yyyy-MM-dd")}"); } } } - private async Task Delete() - { - await Models.Stunde.DeleteEntry(_stunde); - await Shell.Current.GoToAsync($"..?date={_stunde.day.ToString("yyyy-MM-dd")}"); + private async Task Delete() { + await Models.HoursBase.DeleteEntry(DayTime); + await Shell.Current.GoToAsync($"..?date={DayTime.Day.ToString("yyyy-MM-dd")}"); } - private async Task DeleteConfirm() - { - if (ConfirmEvent != null) - { + private async Task DeleteConfirm() { + if (ConfirmEvent != null) { bool answer = await ConfirmEvent.Invoke("Achtung", "Löschen kann nicht ungeschehen gemacht werden. Fortfahren?"); - if (answer) - { + if (answer) { //Löschen - await Models.Stunde.DeleteEntry(_stunde); - await Shell.Current.GoToAsync($"..?date={_stunde.day.ToString("yyyy-MM-dd")}"); - } - else - { //nicht Löschen + await Models.HoursBase.DeleteEntry(DayTime); + await Shell.Current.GoToAsync($"..?date={DayTime.Day.ToString("yyyy-MM-dd")}"); + } else { //nicht Löschen } } } - private async Task LoadSettings() - { - Settings = await Models.Stunde.LoadSettings(); - } + /// /// Anwenden der Query-Parameter /// - async void IQueryAttributable.ApplyQueryAttributes(IDictionary query) - { - await LoadSettings(); + async void IQueryAttributable.ApplyQueryAttributes(IDictionary query) { + var probe = query; - if (query.ContainsKey("load")) - { + if (query.ContainsKey("load")) { //DateTime heute = DateTime.Now; - Stunde = await Models.Stunde.LoadEntry(Convert.ToInt32(query["load"])); - if (System.String.IsNullOrEmpty(Stunde.description)) - { + _dayTime = await Models.HoursBase.LoadEntry(Convert.ToInt32(query["load"])); + if (System.String.IsNullOrEmpty(DayTime.Description)) { AlertEvent?.Invoke(this, "Eintrag hat keine Daten zurückgegeben"); } - SubTitle = Stunde.day.ToString("dddd, d. MMMM yyyy"); + SubTitle = DayTime.Day.ToString("dddd, d. MMMM yyyy"); - OptionsProjekt = new ObservableCollection(Stunde.Projekte); - OptionsGemeinde = new ObservableCollection(Stunde.Gemeinden); - OptionsFreistellung = new ObservableCollection(Stunde.Freistellungen); - OnPropertyChanged(nameof(OptionsGemeinde)); - OnPropertyChanged(nameof(OptionsProjekt)); - OnPropertyChanged(nameof(OptionsFreistellung)); - //OptionsProjekt.FirstOrDefault(x => x.Id == _stunde.projekt); + _dayTime.GemeindeAktiv = OptionsGemeinde.FirstOrDefault(Gemeinde => Gemeinde.Id == DayTime.Gemeinde) ?? new Gemeinde(); - SelectedOptionGemeinde = OptionsGemeinde.FirstOrDefault(item => item.Id == Stunde.gemeinde) ?? new Gemeinde(); - OnPropertyChanged(nameof(SelectedOptionGemeinde)); + _dayTime.ProjektAktiv = OptionsProjekt.FirstOrDefault(Projekt => Projekt.Id == DayTime.Projekt) ?? new Projekt(); - SelectedOptionProjekt = OptionsProjekt.FirstOrDefault(Projekt => Projekt.Id == Stunde.projekt) ?? new Projekt(); - OnPropertyChanged(nameof(SelectedOptionProjekt)); - - SelectedOptionFreistellung = OptionsFreistellung.FirstOrDefault(Freistellung => Freistellung.Id == Stunde.free) ?? new Freistellung(); - OnPropertyChanged(nameof(SelectedOptionFreistellung)); + _dayTime.FreistellungAktiv = OptionsFreistellung.FirstOrDefault(Freistellung => Freistellung.Id == DayTime.Free) ?? new Freistellung(); + OnPropertyChanged(nameof(DayTime)); OnPropertyChanged(nameof(SubTitle)); } - if (query.ContainsKey("date")) - { + if (query.ContainsKey("date")) { Title = "Neuer Eintrag"; DateTime _date = DateTime.ParseExact((string)query["date"], "yyyy-MM-dd", System.Globalization.CultureInfo.InvariantCulture); //Bei neuem Eintrag die vorhandenen des gleichen Tages anzeigen - try - { - DayTimes = await Models.Stunde.LoadDay(_date); - } - catch (Exception) - { + try { + DayTimes = await HoursBase.LoadDay(_date); + } catch (Exception) { //Ein Tag ohne Einträge gibt eine Fehlermeldung, //die soll aber ignoriert werden, weil beim Neueintrag ist das ja Wurscht } - _stunde.day = _date; + DayTime.Day = _date; SubTitle = _date.ToString("dddd, d. MMMM yyyy"); _ = LoadData(); diff --git a/Jugenddienst Stunden/ViewModels/StundenViewModel.cs b/Jugenddienst Stunden/ViewModels/StundenViewModel.cs index 9ace248..085a361 100644 --- a/Jugenddienst Stunden/ViewModels/StundenViewModel.cs +++ b/Jugenddienst Stunden/ViewModels/StundenViewModel.cs @@ -1,5 +1,6 @@ using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; +using Jugenddienst_Stunden.Models; using Jugenddienst_Stunden.Types; using Newtonsoft.Json.Linq; using System.Collections.ObjectModel; @@ -10,15 +11,12 @@ using System.Windows.Input; namespace Jugenddienst_Stunden.ViewModels; -internal class StundenViewModel : ObservableObject, IQueryAttributable, INotifyPropertyChanged -{ - public string Name => AppInfo.Name; - public string Surname => AppInfo.VersionString; - public string MoreInfoUrl => "https://aka.ms/maui"; - public string Message => "Hier werden deine geleisteten Arbeitsstunden aufgelistet"; +/// +/// Stundenliste +/// +internal class StundenViewModel : ObservableObject, IQueryAttributable, INotifyPropertyChanged { + public string LoadOverview => "Lade Summen für " + DateTime.Today.ToString("MMMM"); - //public static DateTime GetDay = DateTime.Today; - //public string ShowDay => "Zeit an Tag " + GetDay.ToString("ddd d. MMM") + ": "; public ICommand NewEntryCommand { get; } public ICommand SelectEntryCommand { get; } @@ -30,32 +28,19 @@ internal class StundenViewModel : ObservableObject, IQueryAttributable, INotifyP public event EventHandler AlertEvent; public event EventHandler InfoEvent; - private Settings Settings { get; set; } + private HoursBase HoursBase = new HoursBase(); + internal Settings Settings = new Settings(); - private bool isRefreshing; - public bool IsRefreshing - { - get => isRefreshing; - set - { - if (isRefreshing != value) - { - isRefreshing = value; - OnPropertyChanged(); - } - } - } - private string _title = Preferences.Default.Get("name", "") + " " + Preferences.Default.Get("surname", ""); - public string Title - { + + private string _title = HoursBase.name + " " + HoursBase.surname; + public string Title { get => _title; set => SetProperty(ref _title, value); } private Hours _hour; - public Hours Hours - { + public Hours Hours { get => _hour; } @@ -67,26 +52,26 @@ internal class StundenViewModel : ObservableObject, IQueryAttributable, INotifyP /// /// Liste der Tageszeiten /// - private ObservableCollection _dayTimes = new ObservableCollection(); - public ObservableCollection DayTimes - { + private List _dayTimes = new List(); + public List DayTimes { get => _dayTimes; - set => SetProperty(ref _dayTimes, value); + set { + SetProperty(ref _dayTimes, value); + OnPropertyChanged(nameof(DayTimes)); + } } /// /// Mindest-Datum für den Datepicker /// - public DateTime MinimumDate - { + public DateTime MinimumDate { get => DateTime.Today.AddDays(-365); } /// /// Höchst-Datum für den Datepicker /// - public DateTime MaximumDate - { + public DateTime MaximumDate { get => DateTime.Today.AddDays(60); } @@ -94,13 +79,10 @@ internal class StundenViewModel : ObservableObject, IQueryAttributable, INotifyP /// Heutiges Datum, wenn das Datum geändert wird, wird auch der Tag geladen /// private DateTime dateToday = DateTime.Today; - public DateTime DateToday - { + public DateTime DateToday { get => dateToday; - set - { - if (dateToday != value) - { + set { + if (dateToday != value) { dateToday = value; //GetDay = value; //OnPropertyChanged(); @@ -113,56 +95,69 @@ internal class StundenViewModel : ObservableObject, IQueryAttributable, INotifyP /// /// Monatsübersicht: Geleistete Stunden /// - public string? ZeitCalculated - { - get => _hour.zeit_total; + public string? ZeitCalculated { + get => Hours.Zeit_total; } /// /// Monatsübersicht: Sollstunden /// - public string? Nominal - { - get => _hour.nominal; + public string? Nominal { + get => Hours.Nominal; } /// /// Monatsübersicht: Differenz zwischen Soll und geleisteten Stunden /// - public string? Overtime - { - get => _hour.overtime; + public string? Overtime { + get => Hours.overtime; } /// /// Monatsübersicht: Restüberstunden insgesamt /// - public string OvertimeMonth - { - get => _hour.overtime_month; + public string OvertimeMonth { + get => Hours.overtime_month; } /// /// Monatsübersicht: Resturlaub /// - public string Holiday - { - get => _hour.holiday; + public string Holiday { + get => Hours.holiday; } + /// + /// Seite neu laden + /// + private bool isRefreshing; + public bool IsRefreshing { + get => isRefreshing; + set { + if (isRefreshing != value) { + isRefreshing = value; + OnPropertyChanged(); + } + } + } + /// + /// Dürfen Gemeinden verwendet werden? + /// + public bool GemeindeAktivSet { get; set; } - + /// + /// Dürfen Projekte verwendet werden? + /// + public bool ProjektAktivSet { get; set; } /// /// CTOR /// - public StundenViewModel() - { - - _hour = new Types.Hours(); + public StundenViewModel() { + _hour = new Hours(); LoadDataCommand = new AsyncRelayCommand(LoadData); NewEntryCommand = new AsyncRelayCommand(NewEntryAsync); @@ -171,18 +166,24 @@ internal class StundenViewModel : ObservableObject, IQueryAttributable, INotifyP RefreshCommand = new Command(async () => await RefreshItemsAsync()); Task task = LoadDay(DateTime.Today); - - - + LoadSettingsAsync(); } + private async void LoadSettingsAsync() { + Settings = await HoursBase.LoadSettings(); + + GemeindeAktivSet = Settings.GemeindeAktivSet; + ProjektAktivSet = Settings.ProjektAktivSet; + + OnPropertyChanged(nameof(GemeindeAktivSet)); + OnPropertyChanged(nameof(ProjektAktivSet)); + + } /// /// Öffnet eine neue Stundeneingabe /// - /// - private async Task NewEntryAsync() - { + private async Task NewEntryAsync() { //Hier muss das Datum übergeben werden //await Shell.Current.GoToAsync(nameof(Views.StundePage)); await Shell.Current.GoToAsync($"{nameof(Views.StundePage)}?date={dateToday:yyyy-MM-dd}"); @@ -191,99 +192,72 @@ internal class StundenViewModel : ObservableObject, IQueryAttributable, INotifyP /// /// Öffnet eine bestehende Stundeneingabe /// - /// - /// - private async Task SelectEntryAsync(DayTime entry) - { - if (entry != null && entry.id != null) - { + private async Task SelectEntryAsync(DayTime entry) { + if (entry != null && entry.Id != null) { //var navigationParameters = new Dictionary { { "load", entry.id } }; //await Shell.Current.GoToAsync($"{nameof(Views.StundePage)}", navigationParameters); - await Shell.Current.GoToAsync($"{nameof(Views.StundePage)}?load={entry.id}"); - } - else AlertEvent?.Invoke(this, "Auswahl enthält keine Daten"); + await Shell.Current.GoToAsync($"{nameof(Views.StundePage)}?load={entry.Id}"); + } else AlertEvent?.Invoke(this, "Auswahl enthält keine Daten"); } - private async Task RefreshList() - { + private async Task RefreshList() { OnPropertyChanged(nameof(DayTimes)); } /// /// Lädt die Monatssummen für die Übersicht /// - /// - private async Task LoadData() - { - try - { - - _hour = await Models.Stunde.LoadData(); + private async Task LoadData() { + try { + _hour = await HoursBase.LoadData(); RefreshProperties(); - } - catch (Exception e) - { + } catch (Exception e) { AlertEvent?.Invoke(this, e.Message); } } + /// /// Lädt die Arbeitszeiten für einen Tag /// - /// - /// - public async Task LoadDay(DateTime date) - { + public async Task LoadDay(DateTime date) { DayTotal = new TimeOnly(0); - - try - { - await LoadSettings(); - DayTimes = await Models.Stunde.LoadDay(date); + LoadSettingsAsync(); + try { + DayTimes = await HoursBase.LoadDay(date); //TODO: Hier muss noch die Berechnung der Stunden erfolgen //Es werden im Moment nur die eingetragenen Stunden gezählt //Auf der Website bekommt der Benutzer hingegen die berechneten Stunden angezeigt (Nachstunden außerhalb des Stundenplanes zählen mehr ...) TimeSpan span = TimeSpan.Zero; - foreach (DayTime dt in DayTimes) - { - span += dt.end - dt.begin; + foreach (DayTime dt in DayTimes) { + span += dt.End - dt.Begin; } DayTotal = TimeOnly.FromTimeSpan(span); - } - catch (Exception e) - { - DayTimes = new ObservableCollection(); + } catch (Exception e) { + DayTimes = new List(); //TODO: hier könnte auch ein Fehler kommen, dann wäre InfoEvent falsch. InfoEvent?.Invoke(this, e.Message); - } - finally - { + } finally { OnPropertyChanged(nameof(DayTotal)); //OnPropertyChanged(nameof(DayTimes)); } } - private async Task LoadSettings() - { - Settings = await Models.Stunde.LoadSettings(); - } - async void IQueryAttributable.ApplyQueryAttributes(IDictionary query) - { - if (query.ContainsKey("date")) - { + + async void IQueryAttributable.ApplyQueryAttributes(IDictionary query) { + if (query.ContainsKey("date")) { await LoadDay(Convert.ToDateTime(query["date"])); } } - private async Task RefreshItemsAsync() - { + private async Task RefreshItemsAsync() { IsRefreshing = true; // Fügen Sie hier die Logik zum Aktualisieren der Daten hinzu @@ -296,8 +270,7 @@ internal class StundenViewModel : ObservableObject, IQueryAttributable, INotifyP /// /// Refreshes all properties /// - private void RefreshProperties() - { + private void RefreshProperties() { OnPropertyChanged(nameof(Nominal)); OnPropertyChanged(nameof(Overtime)); OnPropertyChanged(nameof(OvertimeMonth)); @@ -309,14 +282,10 @@ internal class StundenViewModel : ObservableObject, IQueryAttributable, INotifyP OnPropertyChanged(nameof(MaximumDate)); } - protected void OnPropertyChanged([CallerMemberName] string propertyName = null) - { - try - { + protected void OnPropertyChanged([CallerMemberName] string propertyName = null) { + try { base.OnPropertyChanged(new PropertyChangedEventArgs(propertyName)); - } - catch (Exception ex) - { + } catch (Exception ex) { AlertEvent?.Invoke(this, ex.Message); //Console.WriteLine($"Fehler bei OnPropertyChanged: {ex.Message}"); } diff --git a/Jugenddienst Stunden/Views/LoginPage.xaml.cs b/Jugenddienst Stunden/Views/LoginPage.xaml.cs index b070cc3..0e0ad42 100644 --- a/Jugenddienst Stunden/Views/LoginPage.xaml.cs +++ b/Jugenddienst Stunden/Views/LoginPage.xaml.cs @@ -49,19 +49,19 @@ public partial class LoginPage : ContentPage { if ((currentTime - _lastDetectionTime) > _detectionInterval) { _lastDetectionTime = currentTime; foreach (var barcode in e.Results) { - if (Stunde.apiKey != barcode.Value) { + if (HoursBase.apiKey != barcode.Value) { _ = MainThread.InvokeOnMainThreadAsync(async () => { //await DisplayAlert("Barcode erkannt", $"Barcode: {barcode.Format} - {barcode.Value}", "OK"); try { var tokendata = new TokenData(barcode.Value); - var op = await Models.Operator.LoadData(barcode.Value); - Models.Stunde.apiKey = barcode.Value; - Models.Stunde.name = op.name; - Models.Stunde.surname = op.surname; - Models.Stunde.EmployeeId = int.Parse(op.id); + var op = await Models.HoursBase.LoadOperator(barcode.Value); + Models.HoursBase.apiKey = barcode.Value; + Models.HoursBase.name = op.name; + Models.HoursBase.surname = op.surname; + Models.HoursBase.EmployeeId = int.Parse(op.id); Title = op.name + " " + op.surname; - ServerLabel.Text = "Server: " + tokendata.url.Replace("/appapi", "").Replace("https://", "").Replace("http://", ""); + ServerLabel.Text = "Server: " + tokendata.Url.Replace("/appapi", "").Replace("https://", "").Replace("http://", ""); Preferences.Default.Set("apiKey", barcode.Value); Preferences.Default.Set("name", op.name); @@ -122,18 +122,18 @@ public partial class LoginPage : ContentPage { return; } try { - Types.User response = await Auth.AuthUserPass(username, password, server); + Types.User response = await BaseFunc.AuthUserPass(username, password, server); - var tokendata = new TokenData(response.token); - var op = await Models.Operator.LoadData(response.token); - Models.Stunde.apiKey = response.token; - Models.Stunde.name = op.name; - Models.Stunde.surname = op.surname; - Models.Stunde.EmployeeId = int.Parse(op.id); + var tokendata = new TokenData(response.Token); + var op = await Models.HoursBase.LoadOperator(response.Token); + Models.HoursBase.apiKey = response.Token; + Models.HoursBase.name = op.name; + Models.HoursBase.surname = op.surname; + Models.HoursBase.EmployeeId = int.Parse(op.id); Title = op.name + " " + op.surname; - ServerLabel.Text = "Server: " + tokendata.url.Replace("/appapi", "").Replace("https://", "").Replace("http://", ""); + ServerLabel.Text = "Server: " + tokendata.Url.Replace("/appapi", "").Replace("https://", "").Replace("http://", ""); - Preferences.Default.Set("apiKey", response.token); + Preferences.Default.Set("apiKey", response.Token); Preferences.Default.Set("name", op.name); Preferences.Default.Set("surname", op.surname); Preferences.Default.Set("EmployeeId", int.Parse(op.id)); diff --git a/Jugenddienst Stunden/Views/StundePage.xaml b/Jugenddienst Stunden/Views/StundePage.xaml index 170cb3c..b53dc49 100644 --- a/Jugenddienst Stunden/Views/StundePage.xaml +++ b/Jugenddienst Stunden/Views/StundePage.xaml @@ -25,12 +25,12 @@ - + - + @@ -38,21 +38,21 @@ - + - + - + - + public partial class StundenPage : ContentPage { - /// - /// CTOR - /// - public StundenPage() { - InitializeComponent(); - if (BindingContext is StundenViewModel vm) { - vm.AlertEvent += Vm_AlertEvent; - vm.InfoEvent += Vm_InfoEvent; - } - if (!CheckLogin()) { - NavigateToTargetPage(); - } - //// Bildschirmhöhe abrufen - //var screenHeight = DeviceDisplay.MainDisplayInfo.Height / DeviceDisplay.MainDisplayInfo.Density; + /// + /// CTOR + /// + public StundenPage() { + InitializeComponent(); + if (BindingContext is StundenViewModel vm) { + vm.AlertEvent += Vm_AlertEvent; + vm.InfoEvent += Vm_InfoEvent; + } + if (!CheckLogin()) { + NavigateToTargetPage(); + } + //// Bildschirmhöhe abrufen + //var screenHeight = DeviceDisplay.MainDisplayInfo.Height / DeviceDisplay.MainDisplayInfo.Density; - //// Berechnen der gewünschten Höhe - //var desiredHeight = screenHeight - 450; // Abzüglich der Stundenübersicht - //stundeItems.HeightRequest = desiredHeight; + //// Berechnen der gewünschten Höhe + //var desiredHeight = screenHeight - 450; // Abzüglich der Stundenübersicht + //stundeItems.HeightRequest = desiredHeight; - SizeChanged += OnPageSizeChanged; - } + SizeChanged += OnPageSizeChanged; + } - private void Vm_AlertEvent(object? sender, string e) { - DisplayAlert("Fehler:", e, "OK"); - } - private void Vm_InfoEvent(object? sender, string e) { - DisplayAlert("Information:", e, "OK"); - } + private void Vm_AlertEvent(object? sender, string e) { + DisplayAlert("Fehler:", e, "OK"); + } + private void Vm_InfoEvent(object? sender, string e) { + DisplayAlert("Information:", e, "OK"); + } - /// - /// Beim Laden der Seite den Titel setzen - /// - protected override void OnAppearing() { - base.OnAppearing(); - Title = Preferences.Default.Get("name", "Nicht") + " " + Preferences.Default.Get("surname", "eingeloggt"); - } + /// + /// Beim Laden der Seite den Titel setzen + /// + protected override void OnAppearing() { + base.OnAppearing(); + Title = Preferences.Default.Get("name", "Nicht") + " " + Preferences.Default.Get("surname", "eingeloggt"); + } - private bool CheckLogin() { - return Preferences.Default.Get("apiKey", "") != ""; - } + private bool CheckLogin() { + return Preferences.Default.Get("apiKey", "") != ""; + } - private async void NavigateToTargetPage() { - await Navigation.PushAsync(new LoginPage()); - } + private async void NavigateToTargetPage() { + await Navigation.PushAsync(new LoginPage()); + } - private void OnPageSizeChanged(object sender, EventArgs e) { - double windowHeight = this.Height; - AdjustLayout(windowHeight); - } + private void OnPageSizeChanged(object sender, EventArgs e) { + double windowHeight = this.Height; + AdjustLayout(windowHeight); + } - private void AdjustLayout(double height) { - // Passen Sie Ihre UI-Elemente basierend auf der Fensterhöhe an - stundeItems.HeightRequest = height - 280; //Datepicker Height 50, Monatssummen Height 125, Titel + Navigation Height xyz - } + private void AdjustLayout(double height) { + // Passen Sie Ihre UI-Elemente basierend auf der Fensterhöhe an + stundeItems.HeightRequest = height - 280; //Datepicker Height 50, Monatssummen Height 125, Titel + Navigation Height xyz + } } \ No newline at end of file