Namespaceanpassungen

This commit is contained in:
2024-10-12 16:02:01 +02:00
parent 6557efcb84
commit 1a88514a6f
21 changed files with 837 additions and 847 deletions

View File

@@ -6,27 +6,26 @@ using Microsoft.Maui.LifecycleEvents;
using ZXing.Net.Maui.Controls; using ZXing.Net.Maui.Controls;
namespace Jugenddienst_Stunden { namespace Jugenddienst_Stunden;
public static class MauiProgram { public static class MauiProgram {
public static MauiApp CreateMauiApp() { public static MauiApp CreateMauiApp() {
var builder = MauiApp.CreateBuilder(); var builder = MauiApp.CreateBuilder();
builder builder
.UseMauiApp<App>() .UseMauiApp<App>()
.ConfigureFonts(fonts => { .ConfigureFonts(fonts => {
fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular"); fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold"); fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
}) })
.UseBarcodeReader(); .UseBarcodeReader();
#if DEBUG
builder.Logging.AddDebug();
#endif
return builder.Build();
}
#if DEBUG
builder.Logging.AddDebug();
#endif
return builder.Build();
} }
} }

View File

@@ -1,91 +1,81 @@
using System; using System.Diagnostics;
using System.Diagnostics;
using System.Net.Http;
using System.Text; using System.Text;
using System.Threading.Tasks;
using Jugenddienst_Stunden.Types; using Jugenddienst_Stunden.Types;
using System.Text.Json; using System.Text.Json;
using ZXing.QrCode.Internal;
namespace Jugenddienst_Stunden.Models {
class Auth {
public static async Task<string> GetApiDataWithAuthAsync(string url, string token) { namespace Jugenddienst_Stunden.Models;
// Erstellen eines HttpClient-Objekts
using (HttpClient client = new HttpClient() { Timeout = TimeSpan.FromSeconds(15) }) {
client.DefaultRequestHeaders.Add("Accept", "application/json"); class Auth {
public static async Task<string> GetApiDataWithAuthAsync(string url, string token) {
// Erstellen eines HttpClient-Objekts
using (HttpClient client = new HttpClient() { Timeout = TimeSpan.FromSeconds(15) }) {
// Hinzufügen des Bearer-Tokens zum Authorization-Header client.DefaultRequestHeaders.Add("Accept", "application/json");
client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token);
// Hinzufügen des Bearer-Tokens zum Authorization-Header
client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token);
//Beim Debugging im Lokalen Netz mit meinem Smartphone kommt es hier zu // Senden der Anfrage und Abrufen der Antwort
//system.net.webexception nachricht = socket closed using (HttpResponseMessage HttpResponseMessage = await client.GetAsync(url).ConfigureAwait(false)) {
//Grund: Falscher DNS-Server liefert falsche Server-IP // Überprüfen, ob die Anfrage erfolgreich war
if (HttpResponseMessage.StatusCode == System.Net.HttpStatusCode.OK) {
// Senden der Anfrage und Abrufen der Antwort using (HttpContent HttpContent = HttpResponseMessage.Content) {
using (HttpResponseMessage HttpResponseMessage = await client.GetAsync(url).ConfigureAwait(false)) { // Lesen und Rückgabe der Antwort als String
// Überprüfen, ob die Anfrage erfolgreich war string responseData = await HttpContent.ReadAsStringAsync();
if (HttpResponseMessage.StatusCode == System.Net.HttpStatusCode.OK) { return responseData;
using (HttpContent HttpContent = HttpResponseMessage.Content) {
// Lesen und Rückgabe der Antwort als String
string responseData = await HttpContent.ReadAsStringAsync();
return responseData;
}
} }
} }
} }
return null;
} }
return null;
public static async Task SaveItemAsync(string url, string token, DayTime item, bool isNewItem = false) {
//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);
string json = JsonSerializer.Serialize<DayTime>(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.");
} 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)
Debug.WriteLine(@"\tTodoItem successfully deleted.");
} catch (Exception ex) {
Debug.WriteLine(@"\tERROR {0}", ex.Message);
}
//}
}
} }
public static async Task SaveItemAsync(string url, string token, DayTime item, bool isNewItem = false) {
//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);
string json = JsonSerializer.Serialize<DayTime>(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.");
} 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)
Debug.WriteLine(@"\tTodoItem successfully deleted.");
} catch (Exception ex) {
Debug.WriteLine(@"\tERROR {0}", ex.Message);
}
//}
}
} }

View File

@@ -4,53 +4,52 @@ using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Jugenddienst_Stunden.Models { namespace Jugenddienst_Stunden.Models;
internal class Note { internal class Note {
public string Filename { get; set; } public string Filename { get; set; }
public string Text { get; set; } public string Text { get; set; }
public DateTime Date { get; set; } public DateTime Date { get; set; }
public void Save() => public void Save() =>
File.WriteAllText(System.IO.Path.Combine(FileSystem.AppDataDirectory, Filename), Text); File.WriteAllText(System.IO.Path.Combine(FileSystem.AppDataDirectory, Filename), Text);
public void Delete() => public void Delete() =>
File.Delete(System.IO.Path.Combine(FileSystem.AppDataDirectory, Filename)); File.Delete(System.IO.Path.Combine(FileSystem.AppDataDirectory, Filename));
public static Note Load(string filename) { public static Note Load(string filename) {
filename = System.IO.Path.Combine(FileSystem.AppDataDirectory, filename); filename = System.IO.Path.Combine(FileSystem.AppDataDirectory, filename);
if (!File.Exists(filename)) if (!File.Exists(filename))
throw new FileNotFoundException("Unable to find file on local storage.", filename); throw new FileNotFoundException("Unable to find file on local storage.", filename);
return return
new() { new() {
Filename = Path.GetFileName(filename), Filename = Path.GetFileName(filename),
Text = File.ReadAllText(filename), Text = File.ReadAllText(filename),
Date = File.GetLastWriteTime(filename) Date = File.GetLastWriteTime(filename)
}; };
} }
public static IEnumerable<Note> LoadAll() { public static IEnumerable<Note> LoadAll() {
// Get the folder where the notes are stored. // Get the folder where the notes are stored.
string appDataPath = FileSystem.AppDataDirectory; string appDataPath = FileSystem.AppDataDirectory;
// Use Linq extensions to load the *.notes.txt files. // Use Linq extensions to load the *.notes.txt files.
return Directory return Directory
// Select the file names from the directory // Select the file names from the directory
.EnumerateFiles(appDataPath, "*.notes.txt") .EnumerateFiles(appDataPath, "*.notes.txt")
// Each file name is used to load a note // Each file name is used to load a note
.Select(filename => Note.Load(Path.GetFileName(filename))) .Select(filename => Note.Load(Path.GetFileName(filename)))
// With the final collection of notes, order them by date // With the final collection of notes, order them by date
.OrderByDescending(note => note.Date); .OrderByDescending(note => note.Date);
} }
public Note() { public Note() {
Filename = $"{Path.GetRandomFileName()}.notes.txt"; Filename = $"{Path.GetRandomFileName()}.notes.txt";
Date = DateTime.Now; Date = DateTime.Now;
Text = ""; Text = "";
}
} }
} }

View File

@@ -4,50 +4,49 @@ using Jugenddienst_Stunden.ViewModels;
using Newtonsoft.Json; using Newtonsoft.Json;
using System.Text; using System.Text;
namespace Jugenddienst_Stunden.Models { namespace Jugenddienst_Stunden.Models;
public class Operator : ObservableObject { public class Operator : ObservableObject {
public string id; public string id;
public string name; public string name;
public string surname; public string surname;
public string email; public string email;
public string password; public string password;
public string lang; public string lang;
public string admin; public string admin;
public string aktiv; public string aktiv;
public string department; public string department;
public string department_name; public string department_name;
public string num; public string num;
public string year; public string year;
public event EventHandler<string> AlertEvent; public event EventHandler<string> AlertEvent;
public static async Task<Operator> LoadData(string apiKey) { public static async Task<Operator> LoadData(string apiKey) {
Operator OperatorVar = new Operator(); 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<Operator>(data);
Preferences.Default.Set("name", OperatorVar.name);
Preferences.Default.Set("surname", OperatorVar.surname);
Preferences.Default.Set("apiUrl", tokendata.url);
}
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");
} }
return OperatorVar; if (data != "null") {
OperatorVar = JsonConvert.DeserializeObject<Operator>(data);
Preferences.Default.Set("name", OperatorVar.name);
Preferences.Default.Set("surname", OperatorVar.surname);
Preferences.Default.Set("apiUrl", tokendata.url);
}
} }
return OperatorVar;
} }
} }

View File

@@ -1,175 +1,196 @@
using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.ComponentModel;
using Newtonsoft.Json; using Newtonsoft.Json;
using Microsoft.Maui.Networking;
using Microsoft.Maui.Controls;
using System;
using System.Text;
using System.Text.Json;
using Jugenddienst_Stunden.Types; using Jugenddienst_Stunden.Types;
using System.Collections.Generic;
namespace Jugenddienst_Stunden.Models;
internal class Stunde : ObservableObject {
public DateTime Date { get; set; }
//Default-Werte zum Testen
public static string apiKey = Preferences.Default.Get("apiKey", "M3xraUdoSktrdGowaUZoaStJbDJLWmIyTFhYeDh8aHR0cDovL2hvdXJzLmRhdW5pLm1pbmUubnU6ODEvYXBwYXBp");
public static int EmployeeId = Preferences.Default.Get("employeeId", 3);
public static string name = Preferences.Default.Get("name", "Vorname");
public static string surname = Preferences.Default.Get("surname", "Nachname");
public static string apiUrl = Preferences.Default.Get("apiUrl", "http://hours.dauni.mine.nu:81/appapi");
namespace Jugenddienst_Stunden.Models {
internal class Stunde : ObservableObject {
public DateTime Date { get; set; } public static async Task<Hours> LoadData() {
Preferences.Default.Set("apiKey", "NXw5NDdCcEdLMVNDZTRENmphWG02MjlyeFFDenN8aHR0cDovL2hvdXJzLmRhdW5pLm1pbmUubnU6ODEvYXBwYXBp");
Preferences.Default.Set("name", "Johannes");
Preferences.Default.Set("surname", "Fink");
Preferences.Default.Set("EmployeeId", 5);
Preferences.Default.Set("apiUrl", "http://hours.dauni.mine.nu:81/appapi");
//Default-Werte zum Testen apiKey = Preferences.Default.Get("apiKey", "NXw5NDdCcEdLMVNDZTRENmphWG02MjlyeFFDenN8aHR0cDovL2hvdXJzLmRhdW5pLm1pbmUubnU6ODEvYXBwYXBp");
EmployeeId = Preferences.Default.Get("employeeId", 5);
name = Preferences.Default.Get("name", "Johannes");
surname = Preferences.Default.Get("surname", "Fink");
apiUrl = Preferences.Default.Get("apiUrl", "http://hours.dauni.mine.nu:81/appapi");
//Katharina if (string.IsNullOrEmpty(apiKey)) {
//public static string apiKey = Preferences.Default.Get("apiKey", "MTAyfEJZZnB1L3VwcnhoVms0dDlLZENPZWtUVy85b3xodHRwOi8vaG91cnMuZGF1bmkubWluZS5udTo4MS9hcHBhcGk="); throw new Exception("Kein APIKEY, bitte zuerst Login durchführen");
//public static string name = Preferences.Default.Get("name", "Katharina");
//public static string surname = Preferences.Default.Get("surname", "Weger");
//Christine Feichter
public static string apiKey = Preferences.Default.Get("apiKey", "");
public static int EmployeeId = Preferences.Default.Get("employeeId", 3);
public static string name = Preferences.Default.Get("name", "Vorname");
public static string surname = Preferences.Default.Get("surname", "Nachname");
public static string apiUrl = Preferences.Default.Get("apiUrl", "https://");
//Damian
//public static string apiKey = Preferences.Default.Get("apiKey", "MTU0fGpkQUNYTGkvcjMvVk4rNkMyK0dDQkJmMkFwVXxodHRwOi8vaG91cnMuZGF1bmkubWluZS5udTo4MS9hcHBhcGk=");
//private static readonly string requestUrl = $"{BaseAddress}/appapi?hours";
//public static string apiKey = "Mnx6amdpUkFCdWMvc0lmZ3dWeXRVSWx3VGRDRDh8aHR0cDovL2hvdXJzLmRhdW5pLm1pbmUubnU6ODEvYXBwYXBp"; //Daniel Pichler
//public static string apiKey = "M3xraUdoSktrdGowaUZoaStJbDJLWmIyTFhYeDh8aHR0cDovL2hvdXJzLmRhdW5pLm1pbmUubnU6ODEvYXBwYXBp"; //Le Mair
public static async Task<Hours> 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) {
await App.Current.MainPage.DisplayAlert("Keine Internetverbindung",
"Bitte überprüfen Sie Ihre Internetverbindung und versuchen Sie es erneut.",
"OK");
} 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");
}
hours = JsonConvert.DeserializeObject<Hours>(data);
}
return hours;
} }
public static async Task<Hours> LoadBasicData() { Hours hours = new Hours();
Hours hours = new Hours();
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");
} 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");
}
hours = JsonConvert.DeserializeObject<Hours>(data);
}
return hours;
}
public static async Task<List<DayTime>> LoadDay(DateTime date) {
if (string.IsNullOrEmpty(apiKey)) {
throw new Exception("Kein APIKEY, bitte zuerst Login durchführen");
}
List<DayTime> daytimes = new List<DayTime>();
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");
} else {
var tokendata = new TokenData(apiKey);
//string data = await Auth.GetApiDataWithAuthAsync(requestUrl, apiKey);
string data = await Auth.GetApiDataWithAuthAsync(tokendata.url + "?date=" + date.ToString("yyyy-MM-dd"), tokendata.apiKey);
if (data == "null") {
throw new Exception("Keine Daten für " + date.ToString("ddd. dd. MMM") + " erhalten");
}
if (data == "\"Lalala\"") {
throw new Exception("Problem mit Token");
}
//daytimes = System.Text.Json.JsonSerializer.Deserialize<List<DayTime>>(data);
daytimes = JsonConvert.DeserializeObject<List<DayTime>>(data);
}
//Hours = hours;
return daytimes;
}
public static async Task<DayTime> LoadEntry(int id) {
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");
} else {
var tokendata = new TokenData(apiKey); var tokendata = new TokenData(apiKey);
var data = await Auth.GetApiDataWithAuthAsync(tokendata.url + "?id=" + id, tokendata.apiKey);
//DayTime hours = Hours.daytime.Find(x => x.id == id); //string data = await Auth.GetApiDataWithAuthAsync(requestUrl, apiKey);
DayTime hours = JsonConvert.DeserializeObject<DayTime>(data); string data = await Auth.GetApiDataWithAuthAsync(tokendata.url + "?hours", tokendata.apiKey);
hours.TimeSpanVon = hours.begin.ToTimeSpan();
hours.TimeSpanBis = hours.end.ToTimeSpan(); if (data == "null") {
throw new Exception("Keine Daten erhalten");
}
if (data == "\"Lalala\"") {
throw new Exception("Problem mit Token");
}
hours = JsonConvert.DeserializeObject<Hours>(data);
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)
};
}
public static async Task<DayTime> 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;
}
public static async Task<DayTime> DeleteEntry(DayTime stunde) { //, string begin, string end, string freistellung, string bemerkung) {
var tokendata = new TokenData(apiKey);
await Auth.DeleteItemAsync(tokendata.url + "/entry/" + stunde.id, tokendata.apiKey);
return stunde;
} }
return hours;
} }
/// <summary>
/// Basisdaten: Mitarbeiterdaten, Projekte, Gemeinden, Freistellungen.
/// </summary>
/// <returns></returns>
/// <exception cref="Exception"></exception>
public static async Task<Hours> LoadBasicData() {
Hours hours = new Hours();
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");
} 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");
}
hours = JsonConvert.DeserializeObject<Hours>(data);
}
return hours;
}
/// <summary>
/// Zeiten eines Tages holen
/// </summary>
/// <param name="date"></param>
/// <returns></returns>
/// <exception cref="Exception"></exception>
public static async Task<List<DayTime>> LoadDay(DateTime date) {
if (string.IsNullOrEmpty(apiKey)) {
throw new Exception("Kein APIKEY, bitte zuerst Login durchführen");
}
List<DayTime> daytimes = new List<DayTime>();
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");
} else {
var tokendata = new TokenData(apiKey);
//string data = await Auth.GetApiDataWithAuthAsync(requestUrl, apiKey);
string data = await Auth.GetApiDataWithAuthAsync(tokendata.url + "?date=" + date.ToString("yyyy-MM-dd"), tokendata.apiKey);
if (data == "null") {
throw new Exception("Keine Daten für " + date.ToString("ddd. dd. MMM") + " erhalten");
}
if (data == "\"Lalala\"") {
throw new Exception("Problem mit Token");
}
//daytimes = System.Text.Json.JsonSerializer.Deserialize<List<DayTime>>(data);
daytimes = JsonConvert.DeserializeObject<List<DayTime>>(data);
}
//Hours = hours;
return daytimes;
}
/// <summary>
/// Einzelnen Stundeneintrag holen
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public static async Task<DayTime> LoadEntry(int id) {
var tokendata = new TokenData(apiKey);
var data = await Auth.GetApiDataWithAuthAsync(tokendata.url + "?id=" + id, tokendata.apiKey);
//DayTime hours = Hours.daytime.Find(x => x.id == id);
DayTime hours = JsonConvert.DeserializeObject<DayTime>(data);
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)
};
}
/// <summary>
/// Eintrag speichern
/// </summary>
/// <param name="stunde"></param>
/// <returns></returns>
public static async Task<DayTime> 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;
}
/// <summary>
/// Eintrag löschen
/// </summary>
/// <param name="stunde"></param>
/// <returns></returns>
public static async Task<DayTime> DeleteEntry(DayTime stunde) { //, string begin, string end, string freistellung, string bemerkung) {
var tokendata = new TokenData(apiKey);
await Auth.DeleteItemAsync(tokendata.url + "/entry/" + stunde.id, tokendata.apiKey);
return stunde;
}
} }

View File

@@ -5,19 +5,18 @@ using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Jugenddienst_Stunden.Models { namespace Jugenddienst_Stunden.Models;
class TokenData { class TokenData {
public string token { get; set; } public string token { get; set; }
public string apiKey { get; set; } public string apiKey { get; set; }
public string url { get; set; } public string url { get; set; }
public string operator_id { get; set; } public string operator_id { get; set; }
public TokenData(string apiKey) { public TokenData(string apiKey) {
string dat = Encoding.UTF8.GetString(System.Convert.FromBase64String(apiKey)); string dat = Encoding.UTF8.GetString(System.Convert.FromBase64String(apiKey));
this.token = dat.Split('|')[1]; ; this.token = dat.Split('|')[1]; ;
this.url = dat.Split('|')[2]; ; this.url = dat.Split('|')[2]; ;
this.operator_id = dat.Split('|')[0]; ; this.operator_id = dat.Split('|')[0]; ;
this.apiKey = apiKey; this.apiKey = apiKey;
}
} }
} }

View File

@@ -5,15 +5,14 @@ using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Jugenddienst_Stunden.Types { namespace Jugenddienst_Stunden.Types;
public class Base { public class Base {
public Collection<Projekt> Projekte { get; set; } public Collection<Projekt> Projekte { get; set; }
public Collection<Gemeinde> Gemeinden { get; set; } public Collection<Gemeinde> Gemeinden { get; set; }
public Collection<Freistellung> Freistellungen { get; set; } public Collection<Freistellung> Freistellungen { get; set; }
public int EmployeeId { get; set; } public int EmployeeId { get; set; }
public Hours Hours { get; set; } public Hours Hours { get; set; }
public List<DayTime> daytime { get; set; } public List<DayTime> daytime { get; set; }
}
} }

View File

@@ -1,42 +1,41 @@
using Jugenddienst_Stunden.Models; using Jugenddienst_Stunden.Models;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
namespace Jugenddienst_Stunden.Types { namespace Jugenddienst_Stunden.Types;
/// <summary>
/// Represents a day time entry for an employee.
/// </summary>
public class DayTime {
public int? id { get; set; }
public int EmployeeId { get; set; }
public DateTime day { get; set; }
public int wday { get; set; }
public TimeOnly begin { get; set; }
public TimeOnly end { get; set; }
public string description { get; set; }
public string? free { get; set; }
public bool? approved { get; set; }
public int? type { get; set; }
public int? projekt { get; set; }
public int? gemeinde { get; set; }
public TimeOnly night { get; set; }
public Dictionary<string, TimeOnly> total { get; set; }
public TimeOnly end_print { get; set; }
public TimeSpan TimeSpanVon { get; set; }
public TimeSpan TimeSpanBis { get; set; }
public Collection<Projekt> Projekte { get; set; }
public Collection<Gemeinde> Gemeinden { get; set; }
public Collection<Freistellung> Freistellungen { get; set; }
/// <summary> /// <summary>
/// Represents a day time entry for an employee. /// Gets the active Gemeinde based on the gemeinde ID.
/// </summary> /// </summary>
public class DayTime { public Gemeinde GemeindeAktiv { get; set; }
public int? id { get; set; }
public int EmployeeId { get; set; }
public DateTime day { get; set; }
public int wday { get; set; }
public TimeOnly begin { get; set; }
public TimeOnly end { get; set; }
public string description { get; set; }
public string? free { get; set; }
public bool? approved { get; set; }
public int? type { get; set; }
public int? projekt { get; set; }
public int? gemeinde { get; set; }
public TimeOnly night { get; set; }
public Dictionary<string, TimeOnly> total { get; set; }
public TimeOnly end_print { get; set; }
public TimeSpan TimeSpanVon { get; set; }
public TimeSpan TimeSpanBis { get; set; }
public Collection<Projekt> Projekte { get; set; }
public Collection<Gemeinde> Gemeinden { get; set; }
public Collection<Freistellung> Freistellungen { get; set; }
/// <summary> /// <summary>
/// Gets the active Gemeinde based on the gemeinde ID. /// Gets the active Projekt based on the projekt ID.
/// </summary> /// </summary>
public Gemeinde GemeindeAktiv { get; set; } public Projekt ProjektAktiv { get; set; }
/// <summary> public Freistellung FreistellungAktiv { get; set; }
/// Gets the active Projekt based on the projekt ID.
/// </summary>
public Projekt ProjektAktiv { get; set; }
public Freistellung FreistellungAktiv { get; set; }
}
} }

View File

@@ -4,9 +4,8 @@ using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Jugenddienst_Stunden.Types { namespace Jugenddienst_Stunden.Types;
public class Freistellung { public class Freistellung {
public string Id { get; set; } public string Id { get; set; }
public string Name { get; set; } public string Name { get; set; }
}
} }

View File

@@ -4,20 +4,19 @@ using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Jugenddienst_Stunden.Types namespace Jugenddienst_Stunden.Types;
{
/// <summary>
/// Repräsentiert eine Gemeinde mit einer eindeutigen Id und einem Namen.
/// </summary>
public class Gemeinde {
/// <summary>
/// Eindeutige Id der Gemeinde.
/// </summary>
public int Id { get; set; }
/// <summary> /// <summary>
/// Name der Gemeinde. /// Repräsentiert eine Gemeinde mit einer eindeutigen Id und einem Namen.
/// </summary> /// </summary>
public string Name { get; set; } public class Gemeinde {
} /// <summary>
/// Eindeutige Id der Gemeinde.
/// </summary>
public int Id { get; set; }
/// <summary>
/// Name der Gemeinde.
/// </summary>
public string Name { get; set; }
} }

View File

@@ -1,48 +1,45 @@
 
using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.ComponentModel;
using Jugenddienst_Stunden.Models;
using Newtonsoft.Json; using Newtonsoft.Json;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
namespace Jugenddienst_Stunden.Types namespace Jugenddienst_Stunden.Types;
{
public class Hours : ObservableObject
{
public string zeit;
public string nominal;
//public Dictionary<DateOnly,NominalDay> nominal_day_api;
public List<NominalDay> nominal_day_api;
//public Dictionary<int,NominalWeek> nominal_week_api;
public List<NominalWeek> nominal_week_api;
//public List<string> time_line;
public string zeit_total;
//https://stackoverflow.com/questions/29449641/deserialize-json-when-a-value-can-be-an-object-or-an-empty-array/29450279#29450279 public class Hours : ObservableObject {
//[JsonConverter(typeof(JsonSingleOrEmptyArrayConverter<Hours>))] public string zeit;
//public Dictionary<int,decimal> zeit_total_daily; public string nominal;
//public Dictionary<DateOnly,NominalDay> nominal_day_api;
public List<NominalDay> nominal_day_api;
//public Dictionary<int,NominalWeek> nominal_week_api;
public List<NominalWeek> nominal_week_api;
//public List<string> time_line;
public string zeit_total;
public List<TimeDay> zeit_total_daily_api; //https://stackoverflow.com/questions/29449641/deserialize-json-when-a-value-can-be-an-object-or-an-empty-array/29450279#29450279
public List<DayTime> daytime; //[JsonConverter(typeof(JsonSingleOrEmptyArrayConverter<Hours>))]
//public List<string> wochensumme; //public Dictionary<int,decimal> zeit_total_daily;
public string overtime_month;
public string overtime; public List<TimeDay> zeit_total_daily_api;
//public List<string> overtime_day; public List<DayTime> daytime;
public string zeitausgleich; //public List<string> wochensumme;
public string zeitausgleich_month; public string overtime_month;
public string holiday; public string overtime;
public string krankheit; //public List<string> overtime_day;
public string weiterbildung; public string zeitausgleich;
public string bereitschaft; public string zeitausgleich_month;
public string bereitschaft_month; public string holiday;
//public Operator operator_api; public string krankheit;
public DateTime Today; public string weiterbildung;
public DateTime Date; public string bereitschaft;
public DateTime MinDate; public string bereitschaft_month;
public DateTime MaxDate; //public Operator operator_api;
public Collection<Projekt> Projekte { get; set; } public DateTime Today;
public Collection<Gemeinde> Gemeinden { get; set; } public DateTime Date;
public Collection<Freistellung> Freistellungen { get; set; } public DateTime MinDate;
public int EmployeeId { get; set; } public DateTime MaxDate;
public Collection<Projekt> Projekte { get; set; }
public Collection<Gemeinde> Gemeinden { get; set; }
public Collection<Freistellung> Freistellungen { get; set; }
public int EmployeeId { get; set; }
}
} }

View File

@@ -4,11 +4,10 @@ using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Jugenddienst_Stunden.Models { namespace Jugenddienst_Stunden.Types;
public class NominalDay { public class NominalDay {
public int day_number; public int day_number;
public int month_number; public int month_number;
public decimal hours; public decimal hours;
public DateOnly date; public DateOnly date;
}
} }

View File

@@ -4,11 +4,10 @@ using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Jugenddienst_Stunden.Types namespace Jugenddienst_Stunden.Types;
{
public class NominalWeek public class NominalWeek
{ {
public int week_number; public int week_number;
public decimal hours; public decimal hours;
} }
}

View File

@@ -4,20 +4,19 @@ using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Jugenddienst_Stunden.Types namespace Jugenddienst_Stunden.Types;
{
/// <summary>
/// Repräsentiert ein Projekt mit einer eindeutigen ID und einem Namen.
/// </summary>
public class Projekt {
/// <summary>
/// Holt oder setzt die eindeutige ID des Projekts.
/// </summary>
public int Id { get; set; }
/// <summary> /// <summary>
/// Holt oder setzt den Namen des Projekts. /// Repräsentiert ein Projekt mit einer eindeutigen ID und einem Namen.
/// </summary> /// </summary>
public string Name { get; set; } public class Projekt {
} /// <summary>
/// Holt oder setzt die eindeutige ID des Projekts.
/// </summary>
public int Id { get; set; }
/// <summary>
/// Holt oder setzt den Namen des Projekts.
/// </summary>
public string Name { get; set; }
} }

View File

@@ -4,11 +4,10 @@ using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Jugenddienst_Stunden.Types namespace Jugenddienst_Stunden.Types;
{
public class TimeDay public class TimeDay
{ {
public int Day { get; set; } public int Day { get; set; }
public decimal Hours { get; set; } public decimal Hours { get; set; }
} }
}

View File

@@ -4,11 +4,10 @@ using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Jugenddienst_Stunden.Types namespace Jugenddienst_Stunden.Types;
{
internal class Timetable internal class Timetable
{ {
public List<TimetableEntry> timetable; public List<TimetableEntry> timetable;
public decimal wochensumme; public decimal wochensumme;
} }
}

View File

@@ -4,12 +4,11 @@ using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Jugenddienst_Stunden.Types namespace Jugenddienst_Stunden.Types;
{
internal class TimetableEntry internal class TimetableEntry
{ {
public List<TimeOnly>? von; public List<TimeOnly>? von;
public List<TimeOnly>? bis; public List<TimeOnly>? bis;
public decimal summe { get; set; } public decimal summe { get; set; }
} }
}

View File

@@ -4,17 +4,16 @@ using Microsoft.Maui.Dispatching;
using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.ComponentModel;
//using BarcodeScanning; //using BarcodeScanning;
namespace Jugenddienst_Stunden.ViewModels { namespace Jugenddienst_Stunden.ViewModels;
public class LoginViewModel { public class LoginViewModel {
public string AppTitle => AppInfo.Name; public string AppTitle => AppInfo.Name;
public string Version => AppInfo.VersionString; public string Version => AppInfo.VersionString;
public string Message => "Scanne den QR-Code von deinem Benutzerprofil auf der Stundenseite."; public string Message => "Scanne den QR-Code von deinem Benutzerprofil auf der Stundenseite.";
public string Server { get; set; } = "Server: " + Preferences.Default.Get("apiUrl", "https://").Replace("/appapi",""); public string Server { get; set; } = "Server: " + Preferences.Default.Get("apiUrl","").Replace("/appapi","").Replace("https://","").Replace("http://","");
public string Title { get; set; } = Preferences.Default.Get("name", "") + " " + Preferences.Default.Get("surname", ""); public string Title { get; set; } = Preferences.Default.Get("name", "") + " " + Preferences.Default.Get("surname", "");
}
} }

View File

@@ -2,64 +2,63 @@
using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.ComponentModel;
using System.Windows.Input; using System.Windows.Input;
namespace Jugenddienst_Stunden.ViewModels { namespace Jugenddienst_Stunden.ViewModels;
internal class NoteViewModel : ObservableObject, IQueryAttributable { internal class NoteViewModel : ObservableObject, IQueryAttributable {
private Models.Note _note; private Models.Note _note;
public string Text { public string Text {
get => _note.Text; get => _note.Text;
set { set {
if (_note.Text != value) { if (_note.Text != value) {
_note.Text = value; _note.Text = value;
OnPropertyChanged(); OnPropertyChanged();
}
} }
} }
}
public DateTime Date => _note.Date;
public DateTime Date => _note.Date;
public string Identifier => _note.Filename;
public string Identifier => _note.Filename;
public ICommand SaveCommand { get; private set; }
public ICommand DeleteCommand { get; private set; } public ICommand SaveCommand { get; private set; }
public ICommand DeleteCommand { get; private set; }
public NoteViewModel() {
_note = new Models.Note(); public NoteViewModel() {
SaveCommand = new AsyncRelayCommand(Save); _note = new Models.Note();
DeleteCommand = new AsyncRelayCommand(Delete); SaveCommand = new AsyncRelayCommand(Save);
} DeleteCommand = new AsyncRelayCommand(Delete);
}
public NoteViewModel(Models.Note note) {
_note = note; public NoteViewModel(Models.Note note) {
SaveCommand = new AsyncRelayCommand(Save); _note = note;
DeleteCommand = new AsyncRelayCommand(Delete); SaveCommand = new AsyncRelayCommand(Save);
} DeleteCommand = new AsyncRelayCommand(Delete);
}
private async Task Save() {
_note.Date = DateTime.Now; private async Task Save() {
_note.Save(); _note.Date = DateTime.Now;
await Shell.Current.GoToAsync($"..?saved={_note.Filename}"); _note.Save();
} await Shell.Current.GoToAsync($"..?saved={_note.Filename}");
}
private async Task Delete() {
_note.Delete(); private async Task Delete() {
await Shell.Current.GoToAsync($"..?deleted={_note.Filename}"); _note.Delete();
} await Shell.Current.GoToAsync($"..?deleted={_note.Filename}");
}
void IQueryAttributable.ApplyQueryAttributes(IDictionary<string, object> query) {
if (query.ContainsKey("load")) { void IQueryAttributable.ApplyQueryAttributes(IDictionary<string, object> query) {
_note = Models.Note.Load(query["load"].ToString()); if (query.ContainsKey("load")) {
RefreshProperties(); _note = Models.Note.Load(query["load"].ToString());
} RefreshProperties();
} }
}
public void Reload() {
_note = Models.Note.Load(_note.Filename); public void Reload() {
RefreshProperties(); _note = Models.Note.Load(_note.Filename);
} RefreshProperties();
}
private void RefreshProperties() {
OnPropertyChanged(nameof(Text)); private void RefreshProperties() {
OnPropertyChanged(nameof(Date)); OnPropertyChanged(nameof(Text));
} OnPropertyChanged(nameof(Date));
} }
} }

View File

@@ -10,158 +10,157 @@ using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows.Input; using System.Windows.Input;
namespace Jugenddienst_Stunden.ViewModels { namespace Jugenddienst_Stunden.ViewModels;
internal class StundeViewModel : ObservableObject, IQueryAttributable { internal class StundeViewModel : ObservableObject, IQueryAttributable {
public int id { get; set; } public int id { get; set; }
public string SubTitle { get; set; } = DateTime.Today.ToString("dddd, d. MMM. yyyy"); public string SubTitle { get; set; } = DateTime.Today.ToString("dddd, d. MMM. yyyy");
private DayTime _stunde; private DayTime _stunde;
public DayTime Stunde { get => _stunde; } public DayTime Stunde { get => _stunde; }
public event EventHandler<string> AlertEvent; public event EventHandler<string> AlertEvent;
public event EventHandler<string> InfoEvent; public event EventHandler<string> InfoEvent;
public ObservableCollection<Gemeinde> OptionsGemeinde { get; private set; } public ObservableCollection<Gemeinde> OptionsGemeinde { get; private set; }
public ObservableCollection<Projekt> OptionsProjekt { get; private set; } public ObservableCollection<Projekt> OptionsProjekt { get; private set; }
public ObservableCollection<Freistellung> OptionsFreistellung { get; private set; } public ObservableCollection<Freistellung> OptionsFreistellung { get; private set; }
//private Gemeinde _selectedGemeinde; //private Gemeinde _selectedGemeinde;
public Gemeinde SelectedOptionGemeinde { public Gemeinde SelectedOptionGemeinde {
get => _stunde.GemeindeAktiv; get => _stunde.GemeindeAktiv;
set { set {
if (_stunde.GemeindeAktiv != value) { if (_stunde.GemeindeAktiv != value) {
//_selectedGemeinde = value; //_selectedGemeinde = value;
_stunde.GemeindeAktiv = value; _stunde.GemeindeAktiv = value;
OnPropertyChanged(nameof(SelectedOptionGemeinde)); OnPropertyChanged(nameof(SelectedOptionGemeinde));
}
} }
} }
}
//private Projekt _selectedProjekt; //private Projekt _selectedProjekt;
public Projekt SelectedOptionProjekt { public Projekt SelectedOptionProjekt {
get => _stunde.ProjektAktiv; get => _stunde.ProjektAktiv;
set { set {
if (_stunde.ProjektAktiv != value) { if (_stunde.ProjektAktiv != value) {
//_selectedProjekt = value; //_selectedProjekt = value;
_stunde.ProjektAktiv = value; _stunde.ProjektAktiv = value;
OnPropertyChanged(nameof(SelectedOptionProjekt)); OnPropertyChanged(nameof(SelectedOptionProjekt));
}
} }
} }
}
//private Freistellung _selectedFreistellung; //private Freistellung _selectedFreistellung;
public Freistellung SelectedOptionFreistellung { public Freistellung SelectedOptionFreistellung {
get => _stunde.FreistellungAktiv; get => _stunde.FreistellungAktiv;
set { set {
if (_stunde.FreistellungAktiv != value) { if (_stunde.FreistellungAktiv != value) {
_stunde.FreistellungAktiv = value; _stunde.FreistellungAktiv = value;
OnPropertyChanged(nameof(SelectedOptionFreistellung)); OnPropertyChanged(nameof(SelectedOptionFreistellung));
}
} }
} }
}
public ICommand SaveCommand { get; private set; }
public ICommand DeleteCommand { get; private set; }
//public ICommand LoadDataCommand { get; private set; }
public StundeViewModel() {
_stunde = new DayTime();
SaveCommand = new AsyncRelayCommand(Save);
DeleteCommand = new AsyncRelayCommand(Delete);
}
public ICommand SaveCommand { get; private set; } public StundeViewModel(DayTime stunde) {
public ICommand DeleteCommand { get; private set; } _stunde = stunde;
//public ICommand LoadDataCommand { get; private set; }
SaveCommand = new AsyncRelayCommand(Save);
DeleteCommand = new AsyncRelayCommand(Delete);
}
public StundeViewModel() { private async Task LoadData() {
_stunde = new DayTime(); try {
Hours _hours = await Models.Stunde.LoadBasicData();
SaveCommand = new AsyncRelayCommand(Save); OptionsProjekt = new ObservableCollection<Projekt>(_hours.Projekte);
DeleteCommand = new AsyncRelayCommand(Delete); OptionsGemeinde = new ObservableCollection<Gemeinde>(_hours.Gemeinden);
OptionsFreistellung = new ObservableCollection<Freistellung>(_hours.Freistellungen);
OnPropertyChanged(nameof(OptionsGemeinde));
OnPropertyChanged(nameof(OptionsProjekt));
OnPropertyChanged(nameof(OptionsFreistellung));
_stunde.EmployeeId = _hours.EmployeeId;
} catch (Exception e) {
AlertEvent?.Invoke(this, e.Message);
} }
}
public StundeViewModel(DayTime stunde) { async Task Save() {
_stunde = stunde; await Models.Stunde.SaveEntry(_stunde);
if (_stunde.id != null) {
SaveCommand = new AsyncRelayCommand(Save); await Shell.Current.GoToAsync($"..?saved={_stunde.id}");
DeleteCommand = new AsyncRelayCommand(Delete); } else {
}
private async Task LoadData() {
try {
Hours _hours = await Models.Stunde.LoadBasicData();
OptionsProjekt = new ObservableCollection<Projekt>(_hours.Projekte);
OptionsGemeinde = new ObservableCollection<Gemeinde>(_hours.Gemeinden);
OptionsFreistellung = new ObservableCollection<Freistellung>(_hours.Freistellungen);
OnPropertyChanged(nameof(OptionsGemeinde));
OnPropertyChanged(nameof(OptionsProjekt));
OnPropertyChanged(nameof(OptionsFreistellung));
_stunde.EmployeeId = _hours.EmployeeId;
} catch (Exception e) {
AlertEvent?.Invoke(this, e.Message);
}
}
async Task Save() {
await Models.Stunde.SaveEntry(_stunde);
if (_stunde.id != null) {
await Shell.Current.GoToAsync($"..?saved={_stunde.id}");
} else {
await Shell.Current.GoToAsync($"..?date={_stunde.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")}"); await Shell.Current.GoToAsync($"..?date={_stunde.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")}");
}
async void IQueryAttributable.ApplyQueryAttributes(IDictionary<string, object> query) { async void IQueryAttributable.ApplyQueryAttributes(IDictionary<string, object> query) {
if (query.ContainsKey("load")) { if (query.ContainsKey("load")) {
//DateTime heute = DateTime.Now;
_stunde = await Models.Stunde.LoadEntry(Convert.ToInt32(query["load"]));
if (String.IsNullOrEmpty(_stunde.description)) {
AlertEvent?.Invoke(this, "Eintrag hat keine Daten zurückgegeben");
}
SubTitle = _stunde.day.ToString("dddd, d. MMM. yyyy");
OptionsProjekt = new ObservableCollection<Projekt>(_stunde.Projekte);
OptionsGemeinde = new ObservableCollection<Gemeinde>(_stunde.Gemeinden);
OptionsFreistellung = new ObservableCollection<Freistellung>(_stunde.Freistellungen);
OnPropertyChanged(nameof(OptionsGemeinde));
OnPropertyChanged(nameof(OptionsProjekt));
OnPropertyChanged(nameof(OptionsFreistellung));
//OptionsProjekt.FirstOrDefault(x => x.Id == _stunde.projekt);
SelectedOptionGemeinde = OptionsGemeinde.FirstOrDefault(item => item.Id == _stunde.gemeinde) ?? new Gemeinde();
OnPropertyChanged(nameof(SelectedOptionGemeinde));
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));
OnPropertyChanged(nameof(Stunde));
OnPropertyChanged(nameof(SubTitle));
//DateTime heute = DateTime.Now;
_stunde = await Models.Stunde.LoadEntry(Convert.ToInt32(query["load"]));
if (String.IsNullOrEmpty(_stunde.description)) {
AlertEvent?.Invoke(this, "Eintrag hat keine Daten zurückgegeben");
} }
if (query.ContainsKey("date")) { SubTitle = _stunde.day.ToString("dddd, d. MMM. yyyy");
SubTitle = DateTime.ParseExact((string)query["date"], "yyyy-MM-dd", System.Globalization.CultureInfo.InvariantCulture).ToString("dddd, d. MMM. yyyy");
_stunde.day = DateTime.ParseExact((string)query["date"], "yyyy-MM-dd", System.Globalization.CultureInfo.InvariantCulture); OptionsProjekt = new ObservableCollection<Projekt>(_stunde.Projekte);
_ = LoadData(); OptionsGemeinde = new ObservableCollection<Gemeinde>(_stunde.Gemeinden);
OnPropertyChanged(nameof(SubTitle)); OptionsFreistellung = new ObservableCollection<Freistellung>(_stunde.Freistellungen);
} OnPropertyChanged(nameof(OptionsGemeinde));
OnPropertyChanged(nameof(OptionsProjekt));
OnPropertyChanged(nameof(OptionsFreistellung));
//OptionsProjekt.FirstOrDefault(x => x.Id == _stunde.projekt);
SelectedOptionGemeinde = OptionsGemeinde.FirstOrDefault(item => item.Id == _stunde.gemeinde) ?? new Gemeinde();
OnPropertyChanged(nameof(SelectedOptionGemeinde));
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));
OnPropertyChanged(nameof(Stunde));
OnPropertyChanged(nameof(SubTitle));
} }
if (query.ContainsKey("date")) {
SubTitle = DateTime.ParseExact((string)query["date"], "yyyy-MM-dd", System.Globalization.CultureInfo.InvariantCulture).ToString("dddd, d. MMM. yyyy");
_stunde.day = DateTime.ParseExact((string)query["date"], "yyyy-MM-dd", System.Globalization.CultureInfo.InvariantCulture);
_ = LoadData();
OnPropertyChanged(nameof(SubTitle));
}
} }
} }

View File

@@ -11,199 +11,198 @@ using System.Globalization;
using System; using System;
namespace Jugenddienst_Stunden.ViewModels { namespace Jugenddienst_Stunden.ViewModels;
internal class StundenViewModel : ObservableObject, IQueryAttributable { internal class StundenViewModel : ObservableObject, IQueryAttributable {
public string Name => AppInfo.Name; public string Name => AppInfo.Name;
public string Surname => AppInfo.VersionString; public string Surname => AppInfo.VersionString;
public string MoreInfoUrl => "https://aka.ms/maui"; public string MoreInfoUrl => "https://aka.ms/maui";
public string Message => "Hier werden deine geleisteten Arbeitsstunden aufgelistet"; public string Message => "Hier werden deine geleisteten Arbeitsstunden aufgelistet";
public string LoadOverview => "Lade Summen für " + DateTime.Today.ToString("MMMM"); public string LoadOverview => "Lade Summen für " + DateTime.Today.ToString("MMMM");
public static DateTime GetDay = DateTime.Today; public static DateTime GetDay = DateTime.Today;
public string ShowDay => "Zeit an Tag " + GetDay.ToString("ddd d. MMM") + ": "; public string ShowDay => "Zeit an Tag " + GetDay.ToString("ddd d. MMM") + ": ";
public int id { get; set; } public int id { get; set; }
public ICommand NewEntryCommand { get; } public ICommand NewEntryCommand { get; }
public ICommand SelectEntryCommand { get; } public ICommand SelectEntryCommand { get; }
public ICommand LoadDataCommand { get; private set; } public ICommand LoadDataCommand { get; private set; }
public event EventHandler<string> AlertEvent; public event EventHandler<string> AlertEvent;
public event EventHandler<string> InfoEvent; public event EventHandler<string> InfoEvent;
public object Stunden { get; } public object Stunden { get; }
private List<DayTime> _stunde;
public List<DayTime> Stunde {
get => _stunde;
}
private Hours _hour;
public Hours Hours {
get => _hour;
}
public string ZeitDone {
get => _hour.zeit;
}
public string ZeitCalculated {
get => _hour.zeit_total;
}
public string Nominal {
get => _hour.nominal;
}
public string Overtime {
get => _hour.overtime;
}
public string OvertimeMonth {
get => _hour.overtime_month;
}
public string Holiday {
get => _hour.holiday;
}
public TimeOnly DayTotal { get; set; }
public List<DayTime> DayTimes {
get => _hour.daytime;
set {
if (_hour.daytime != value) {
_hour.daytime = value;
OnPropertyChanged();
}
}
}
public DateTime MinimumDate {
//get => _hour.MinDate;
//get => DateTime.Today.AddDays(-21);
get => DateTime.Today.AddDays(-365);
}
public DateTime MaximumDate {
//get => _hour.MaxDate;
get => DateTime.Today.AddDays(60);
}
private DateTime dateToday = DateTime.Today;
public DateTime DateToday {
get => dateToday;
set {
if (dateToday != value) {
dateToday = value;
GetDay = value;
OnPropertyChanged();
_ = LoadDay(value); // Use discard operator to explicitly ignore the returned Task
//RefreshProperties();
OnPropertyChanged(nameof(TimeDay));
OnPropertyChanged(nameof(ShowDay));
OnPropertyChanged(nameof(DayTimes));
}
}
}
public DateTime Date {
get => _hour.Date;
}
public List<TimeDay> ZeitTotalDaily {
get => _hour.zeit_total_daily_api;
}
public string Title { get; set; } = Preferences.Default.Get("name", "") + " " + Preferences.Default.Get("surname", "");
public List<TimeDay> TimeDay { get; set; }
public static string apiKey = Preferences.Default.Get("apiKey", "");
public StundenViewModel() {
_hour = new Types.Hours();
LoadDataCommand = new AsyncRelayCommand(LoadData);
NewEntryCommand = new AsyncRelayCommand(NewEntryAsync);
SelectEntryCommand = new AsyncRelayCommand<DayTime>(SelectEntryAsync);
_ = LoadDay(DateTime.Today);
OnPropertyChanged(nameof(DayTimes));
}
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.ToString("yyyy-MM-dd")}");
}
private async Task SelectEntryAsync(DayTime entry) {
if (entry != null && entry.id != null)
await Shell.Current.GoToAsync($"{nameof(Views.StundePage)}?load={entry.id}");
else AlertEvent?.Invoke(this, "Auswahl enthält keine Daten");
}
private async Task LoadData() {
try {
_hour = await Models.Stunde.LoadData();
RefreshProperties();
} catch (Exception e) {
AlertEvent?.Invoke(this, e.Message);
}
}
public async Task LoadDay(DateTime date) {
try {
_hour.daytime = await Models.Stunde.LoadDay(date);
////if (_hour.zeit_total_daily_api != null) {
////TimeDay = _hour.zeit_total_daily_api.Where(static p => p.Day == GetDay.Day).ToList() ?? new List<TimeDay> { new TimeDay { Day = GetDay.Day, Hours = 0 } };
//RefreshProperties();
//Hier werden im Moment noch nur die eingetragenen Stunden gezählt
//Auf der Website bekommt der Benutzer die berechneten Stunden angezeigt (Nachstunden außerhalb des Stundenplanes zählen mehr ...)
TimeSpan span = TimeSpan.Zero;
foreach (DayTime dt in _hour.daytime) {
span += dt.end - dt.begin;
}
DayTotal = TimeOnly.FromTimeSpan(span);
OnPropertyChanged(nameof(ShowDay));
OnPropertyChanged(nameof(TimeDay));
OnPropertyChanged(nameof(DayTotal));
OnPropertyChanged(nameof(DayTimes));
////}
} catch (Exception e) {
DayTimes = new List<DayTime>();
DayTotal = new TimeOnly(0);
OnPropertyChanged(nameof(DayTotal));
InfoEvent?.Invoke(this, e.Message);
}
}
async void IQueryAttributable.ApplyQueryAttributes(IDictionary<string, object> query) {
if (query.ContainsKey("date")) {
await LoadDay(Convert.ToDateTime(query["date"]));
}
}
private void RefreshProperties() {
OnPropertyChanged(nameof(Nominal));
OnPropertyChanged(nameof(Overtime));
OnPropertyChanged(nameof(OvertimeMonth));
OnPropertyChanged(nameof(ZeitCalculated));
OnPropertyChanged(nameof(ZeitDone));
OnPropertyChanged(nameof(Holiday));
OnPropertyChanged(nameof(Hours));
OnPropertyChanged(nameof(Title));
OnPropertyChanged(nameof(ZeitTotalDaily));
OnPropertyChanged(nameof(TimeDay));
OnPropertyChanged(nameof(MinimumDate));
OnPropertyChanged(nameof(MaximumDate));
OnPropertyChanged(nameof(ShowDay));
//OnPropertyChanged(nameof(DateToday));
}
private List<DayTime> _stunde;
public List<DayTime> Stunde {
get => _stunde;
} }
private Hours _hour;
public Hours Hours {
get => _hour;
}
public string ZeitDone {
get => _hour.zeit;
}
public string ZeitCalculated {
get => _hour.zeit_total;
}
public string Nominal {
get => _hour.nominal;
}
public string Overtime {
get => _hour.overtime;
}
public string OvertimeMonth {
get => _hour.overtime_month;
}
public string Holiday {
get => _hour.holiday;
}
public TimeOnly DayTotal { get; set; }
public List<DayTime> DayTimes {
get => _hour.daytime;
set {
if (_hour.daytime != value) {
_hour.daytime = value;
OnPropertyChanged();
}
}
}
public DateTime MinimumDate {
//get => _hour.MinDate;
//get => DateTime.Today.AddDays(-21);
get => DateTime.Today.AddDays(-365);
}
public DateTime MaximumDate {
//get => _hour.MaxDate;
get => DateTime.Today.AddDays(60);
}
private DateTime dateToday = DateTime.Today;
public DateTime DateToday {
get => dateToday;
set {
if (dateToday != value) {
dateToday = value;
GetDay = value;
OnPropertyChanged();
_ = LoadDay(value); // Use discard operator to explicitly ignore the returned Task
//RefreshProperties();
OnPropertyChanged(nameof(TimeDay));
OnPropertyChanged(nameof(ShowDay));
OnPropertyChanged(nameof(DayTimes));
}
}
}
public DateTime Date {
get => _hour.Date;
}
public List<TimeDay> ZeitTotalDaily {
get => _hour.zeit_total_daily_api;
}
public string Title { get; set; } = Preferences.Default.Get("name", "") + " " + Preferences.Default.Get("surname", "");
public List<TimeDay> TimeDay { get; set; }
public static string apiKey = Preferences.Default.Get("apiKey", "");
public StundenViewModel() {
_hour = new Types.Hours();
LoadDataCommand = new AsyncRelayCommand(LoadData);
NewEntryCommand = new AsyncRelayCommand(NewEntryAsync);
SelectEntryCommand = new AsyncRelayCommand<DayTime>(SelectEntryAsync);
_ = LoadDay(DateTime.Today);
OnPropertyChanged(nameof(DayTimes));
}
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.ToString("yyyy-MM-dd")}");
}
private async Task SelectEntryAsync(DayTime entry) {
if (entry != null && entry.id != null)
await Shell.Current.GoToAsync($"{nameof(Views.StundePage)}?load={entry.id}");
else AlertEvent?.Invoke(this, "Auswahl enthält keine Daten");
}
private async Task LoadData() {
try {
_hour = await Models.Stunde.LoadData();
RefreshProperties();
} catch (Exception e) {
AlertEvent?.Invoke(this, e.Message);
}
}
public async Task LoadDay(DateTime date) {
try {
_hour.daytime = await Models.Stunde.LoadDay(date);
////if (_hour.zeit_total_daily_api != null) {
////TimeDay = _hour.zeit_total_daily_api.Where(static p => p.Day == GetDay.Day).ToList() ?? new List<TimeDay> { new TimeDay { Day = GetDay.Day, Hours = 0 } };
//RefreshProperties();
//Hier werden im Moment noch nur die eingetragenen Stunden gezählt
//Auf der Website bekommt der Benutzer die berechneten Stunden angezeigt (Nachstunden außerhalb des Stundenplanes zählen mehr ...)
TimeSpan span = TimeSpan.Zero;
foreach (DayTime dt in _hour.daytime) {
span += dt.end - dt.begin;
}
DayTotal = TimeOnly.FromTimeSpan(span);
OnPropertyChanged(nameof(ShowDay));
OnPropertyChanged(nameof(TimeDay));
OnPropertyChanged(nameof(DayTotal));
OnPropertyChanged(nameof(DayTimes));
////}
} catch (Exception e) {
DayTimes = new List<DayTime>();
DayTotal = new TimeOnly(0);
OnPropertyChanged(nameof(DayTotal));
InfoEvent?.Invoke(this, e.Message);
}
}
async void IQueryAttributable.ApplyQueryAttributes(IDictionary<string, object> query) {
if (query.ContainsKey("date")) {
await LoadDay(Convert.ToDateTime(query["date"]));
}
}
private void RefreshProperties() {
OnPropertyChanged(nameof(Nominal));
OnPropertyChanged(nameof(Overtime));
OnPropertyChanged(nameof(OvertimeMonth));
OnPropertyChanged(nameof(ZeitCalculated));
OnPropertyChanged(nameof(ZeitDone));
OnPropertyChanged(nameof(Holiday));
OnPropertyChanged(nameof(Hours));
OnPropertyChanged(nameof(Title));
OnPropertyChanged(nameof(ZeitTotalDaily));
OnPropertyChanged(nameof(TimeDay));
OnPropertyChanged(nameof(MinimumDate));
OnPropertyChanged(nameof(MaximumDate));
OnPropertyChanged(nameof(ShowDay));
//OnPropertyChanged(nameof(DateToday));
}
} }