Vorbereitungen für 1.0.6

Beachte die Einstellung ob Projekte und Gemeinden aktiv sind.
Verbiete Änderungen an der Freistellung, wenn sie genehmigt wurde.
Vereinfache das Speichern der Einstellungen
Bessere Fehlerbehandlung, einheitlichere API
This commit is contained in:
2024-10-22 17:42:35 +02:00
parent ff145b2c7f
commit 45c53c85ce
11 changed files with 350 additions and 293 deletions

View File

@@ -20,18 +20,21 @@ public static class MauiProgram {
.UseBarcodeReader(); .UseBarcodeReader();
#if DEBUG #if DEBUG
if (GlobalVar.ApiKey == null) {
//Preferences.Default.Set("apiKey
//Preferences.Default.Set("apiKey", "M3xneWlWNG85TmNIcmo1NnpxWkxVYS9JMDBFRlV8aHR0cDovL2hvdXJzLmRhdW5pLm1pbmUubnU6ODEvYXBwYXBp"); //Preferences.Default.Set("apiKey", "M3xneWlWNG85TmNIcmo1NnpxWkxVYS9JMDBFRlV8aHR0cDovL2hvdXJzLmRhdW5pLm1pbmUubnU6ODEvYXBwYXBp");
//Preferences.Default.Set("name", "Testserver: Lea"); //Preferences.Default.Set("name", "Testserver: Lea");
//Preferences.Default.Set("surname", "Mair"); //Preferences.Default.Set("surname", "Mair");
//Preferences.Default.Set("EmployeeId", 3); //Preferences.Default.Set("EmployeeId", 3);
//Preferences.Default.Set("apiUrl", "http://hours.dauni.mine.nu:81/appapi"); //Preferences.Default.Set("apiUrl", "http://hours.dauni.mine.nu:81/appapi");
HoursBase HoursBase = new HoursBase(); //HoursBase HoursBase = new HoursBase();
HoursBase.apiKey = Preferences.Default.Get("apiKey", "MTQxfHNkdFptQkNZTXlPT3ZyMHNBZDl0UnVxNExMRXxodHRwOi8vaG91cnMuZGF1bmkubWluZS5udTo4MS9hcHBhcGk="); //HoursBase.tokendata = new TokenData("MTQxfHNkdFptQkNZTXlPT3ZyMHNBZDl0UnVxNExMRXxodHRwOi8vaG91cnMuZGF1bmkubWluZS5udTo4MS9hcHBhcGk=");
HoursBase.name = Preferences.Default.Get("name", "Testserver: Isabell"); GlobalVar.ApiKey = Preferences.Default.Get("apiKey", "MTQxfHNkdFptQkNZTXlPT3ZyMHNBZDl0UnVxNExMRXxodHRwOi8vaG91cnMuZGF1bmkubWluZS5udTo4MS9hcHBhcGk=");
HoursBase.surname = Preferences.Default.Get("surname", "Biasi"); GlobalVar.Name = Preferences.Default.Get("name", "Testserver: Isabell");
HoursBase.EmployeeId = Preferences.Default.Get("EmployeeId", 141); GlobalVar.Surname = Preferences.Default.Get("surname", "Biasi");
HoursBase.apiUrl = Preferences.Default.Get("apiUrl", "http://hours.dauni.mine.nu:81/appapi"); GlobalVar.EmployeeId = Preferences.Default.Get("EmployeeId", 141);
GlobalVar.ApiUrl = Preferences.Default.Get("apiUrl", "http://hours.dauni.mine.nu:81/appapi");
}
builder.Logging.AddDebug(); builder.Logging.AddDebug();
#endif #endif

View File

@@ -1,7 +1,5 @@
using Jugenddienst_Stunden.Types; using Jugenddienst_Stunden.Types;
using Newtonsoft.Json; using Newtonsoft.Json;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Text; using System.Text;
using System.Text.Json; using System.Text.Json;
@@ -77,8 +75,9 @@ internal static class BaseFunc {
// Lesen und Rückgabe der Antwort als String // Lesen und Rückgabe der Antwort als String
string responseData = await HttpContent.ReadAsStringAsync(); string responseData = await HttpContent.ReadAsStringAsync();
User userData = System.Text.Json.JsonSerializer.Deserialize<User>(responseData) ?? throw new Exception("Fehler beim Deserialisieren der Daten"); BaseResponse res = JsonConvert.DeserializeObject<BaseResponse>(responseData) ?? throw new Exception("Fehler beim Deserialisieren der Daten");
return userData; //User userData = System.Text.Json.JsonSerializer.Deserialize<User>(responseData) ?? throw new Exception("Fehler beim Deserialisieren der Daten");
return res.user;
} }
} }
} }
@@ -90,7 +89,7 @@ internal static class BaseFunc {
internal static HoursBase Load(string filename) { internal 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))
@@ -98,8 +97,6 @@ internal static class BaseFunc {
return return
new() { new() {
//Filename = Path.GetFileName(filename),
//Text = File.ReadAllText(filename),
Date = File.GetLastWriteTime(filename) Date = File.GetLastWriteTime(filename)
}; };
} }
@@ -129,11 +126,11 @@ internal static class BaseFunc {
} }
//Gemeinde ist ein Pflichtfeld //Gemeinde ist ein Pflichtfeld
if (item.GemeindeAktiv == null) { if (item.GemeindeAktiv == null && GlobalVar.Settings.GemeindeAktivSet) {
throw new Exception("Gemeinde nicht gewählt"); throw new Exception("Gemeinde nicht gewählt");
} }
//Projekt ist ein Pflichtfeld //Projekt ist ein Pflichtfeld
if (item.ProjektAktiv == null) { if (item.ProjektAktiv == null && GlobalVar.Settings.ProjektAktivSet) {
throw new Exception("Projekt nicht gewählt"); throw new Exception("Projekt nicht gewählt");
} }
//Keine Beschreibung //Keine Beschreibung

View File

@@ -0,0 +1,26 @@
using Jugenddienst_Stunden.Types;
namespace Jugenddienst_Stunden.Models;
internal static class GlobalVar {
public static string ApiKey {
get => Preferences.Default.Get("apiKey", "");
set => Preferences.Default.Set("apiKey", value);
}
public static int EmployeeId {
get => Preferences.Default.Get("EmployeeId", 0);
set => Preferences.Default.Set("EmployeeId", value);
}
public static string Name {
get => Preferences.Default.Get("name", "Nicht");
set => Preferences.Default.Set("name", value);
}
public static string Surname {
get => Preferences.Default.Get("surname", "Eingeloggt");
set => Preferences.Default.Set("surname", value);
}
public static string ApiUrl {
get => Preferences.Default.Get("apiUrl", "");
set => Preferences.Default.Set("apiUrl", value);
}
public static Settings Settings { get; set; }
}

View File

@@ -1,106 +1,61 @@
using Jugenddienst_Stunden.Types; using Jugenddienst_Stunden.Types;
using Newtonsoft.Json; using Newtonsoft.Json;
using System.Collections.ObjectModel;
namespace Jugenddienst_Stunden.Models; namespace Jugenddienst_Stunden.Models;
internal class HoursBase { internal static 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;
/// <summary>
/// what can be: settings, hours, date=YYYY-MM-DD, id=<int>
/// </summary>
internal static async Task<BaseResponse> LoadBase(string what) {
string data = await BaseFunc.GetApiDataWithAuthAsync(GlobalVar.ApiUrl + "?"+what, GlobalVar.ApiKey);
BaseResponse res = JsonConvert.DeserializeObject<BaseResponse>(data) ?? throw new Exception("Fehler beim Deserialisieren der Daten");
return res;
}
/// <summary> /// <summary>
/// Einstellungen /// Einstellungen
/// </summary> /// </summary>
internal async Task<Settings> LoadSettings() { internal static async Task<Settings> LoadSettings() {
string data = await BaseFunc.GetApiDataWithAuthAsync(GlobalVar.ApiUrl + "?settings", GlobalVar.ApiKey);
string data = await BaseFunc.GetApiDataWithAuthAsync(tokendata.Url + "?settings", tokendata.ApiKey); BaseResponse res = JsonConvert.DeserializeObject<BaseResponse>(data) ?? throw new Exception("Fehler beim Deserialisieren der Daten");
return res.settings;
Settings _settings = JsonConvert.DeserializeObject<Settings>(data);
return _settings;
} }
/// <summary> /// <summary>
/// Daten laden /// Daten laden
/// </summary> /// </summary>
internal async Task<Hours> LoadData() { internal static async Task<Hours> LoadData() {
string data = await BaseFunc.GetApiDataWithAuthAsync(GlobalVar.ApiUrl + "?hours", GlobalVar.ApiKey);
Hours hours = new Hours(); BaseResponse res = JsonConvert.DeserializeObject<BaseResponse>(data) ?? throw new Exception("Fehler beim Deserialisieren der Daten");
return res.hour;
var tokendata = new TokenData(apiKey);
string data = await BaseFunc.GetApiDataWithAuthAsync(tokendata.Url + "?hours", tokendata.ApiKey);
hours = JsonConvert.DeserializeObject<Hours>(data) ?? throw new Exception("Fehler beim Deserialisieren der Daten");
return hours;
} }
/// <summary> public static async Task<User> LoadUser(string apiKey) {
/// Basisdaten: Mitarbeiterdaten, Projekte, Gemeinden, Freistellungen. string data = await BaseFunc.GetApiDataWithAuthAsync(GlobalVar.ApiUrl, apiKey);
/// </summary> BaseResponse res = JsonConvert.DeserializeObject<BaseResponse>(data) ?? throw new Exception("Fehler beim Deserialisieren der Daten");
internal static async Task<Hours> LoadBasicData() { return res.user;
Hours hours = new Hours();
string data = await BaseFunc.GetApiDataWithAuthAsync(tokendata.Url + "?basic", tokendata.ApiKey);
hours = JsonConvert.DeserializeObject<Hours>(data) ?? throw new Exception("Fehler beim Deserialisieren der Daten");
return hours;
} }
public static async Task<Operator> LoadOperator(string apiKey) {
Operator OperatorVar = new Operator();
string data = await BaseFunc.GetApiDataWithAuthAsync(tokendata.Url, tokendata.ApiKey);
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;
}
/// <summary> /// <summary>
/// Zeiten eines Tages holen /// Zeiten eines Tages holen
/// </summary> /// </summary>
internal async Task<List<DayTime>> LoadDay(DateTime date) { internal static async Task<List<DayTime>> LoadDay(DateTime date) {
string data = await BaseFunc.GetApiDataWithAuthAsync(GlobalVar.ApiUrl + "?date=" + date.ToString("yyyy-MM-dd"), GlobalVar.ApiKey);
string data = await BaseFunc.GetApiDataWithAuthAsync(tokendata.Url + "?date=" + date.ToString("yyyy-MM-dd"), tokendata.ApiKey); BaseResponse res = JsonConvert.DeserializeObject<BaseResponse>(data) ?? throw new Exception("Fehler beim Deserialisieren der Daten");
return res.daytimes;
//List<DayTime> daytimes = System.Text.Json.JsonSerializer.Deserialize<List<DayTime>>(data) ?? throw new Exception("Fehler beim Deserialisieren der Daten");
List<DayTime> daytimes = JsonConvert.DeserializeObject<List<DayTime>>(data);
//List<DayTime> daytimes = JsonConvert.DeserializeObject<List<DayTime>>(data) ?? throw new Exception("Fehler beim Deserialisieren der Daten");
return daytimes;
} }
/// <summary> /// <summary>
/// Einzelnen Stundeneintrag holen /// Einzelnen Stundeneintrag holen
/// </summary> /// </summary>
internal static async Task<DayTime> LoadEntry(int id) { internal static async Task<DayTime> LoadEntry(int id) {
string data = await BaseFunc.GetApiDataWithAuthAsync(GlobalVar.ApiUrl + "?id=" + id, GlobalVar.ApiKey);
string data = await BaseFunc.GetApiDataWithAuthAsync(tokendata.Url + "?id=" + id, tokendata.ApiKey); BaseResponse res = JsonConvert.DeserializeObject<BaseResponse>(data) ?? throw new Exception("Fehler beim Deserialisieren der Daten");
res.daytime.TimeSpanVon = res.daytime.Begin.ToTimeSpan();
//DayTime hours = Hours.daytime.Find(x => x.id == id); res.daytime.TimeSpanBis = res.daytime.End.ToTimeSpan();
DayTime hours = JsonConvert.DeserializeObject<DayTime>(data) ?? throw new Exception("Fehler beim Deserialisieren der Daten"); return res.daytime;
hours.TimeSpanVon = hours.Begin.ToTimeSpan();
hours.TimeSpanBis = hours.End.ToTimeSpan();
return hours;
} }
/// <summary> /// <summary>
@@ -111,7 +66,7 @@ internal class HoursBase {
bool isNew = false; bool isNew = false;
if (stunde.Id == null) if (stunde.Id == null)
isNew = true; isNew = true;
await BaseFunc.SaveItemAsync(tokendata.Url, tokendata.ApiKey, stunde, isNew); await BaseFunc.SaveItemAsync(GlobalVar.ApiUrl, GlobalVar.ApiKey, stunde, isNew);
return stunde; return stunde;
} }
@@ -120,6 +75,6 @@ internal class HoursBase {
/// Eintrag löschen /// Eintrag löschen
/// </summary> /// </summary>
internal static async Task DeleteEntry(DayTime stunde) { internal static async Task DeleteEntry(DayTime stunde) {
await BaseFunc.DeleteItemAsync(tokendata.Url + "/entry/" + stunde.Id, tokendata.ApiKey); await BaseFunc.DeleteItemAsync(GlobalVar.ApiUrl + "/entry/" + stunde.Id, GlobalVar.ApiKey);
} }
} }

View File

@@ -2,7 +2,7 @@
using Newtonsoft.Json; using Newtonsoft.Json;
namespace Jugenddienst_Stunden.Models; namespace Jugenddienst_Stunden.Models;
internal class Operator : HoursBase { internal class Operator {
public string? id; public string? id;
public string? name; public string? name;
public string? surname; public string? surname;
@@ -16,8 +16,6 @@ internal class Operator : HoursBase {
public string? num; public string? num;
public string? year; public string? year;
public event EventHandler<string>? AlertEvent; public event EventHandler<string>? AlertEvent;
} }

View File

@@ -0,0 +1,36 @@
using Jugenddienst_Stunden.Models;
namespace Jugenddienst_Stunden.Types;
internal class BaseResponse {
public Settings settings { get; set; }
/// <summary>
/// Monatsübersicht
/// </summary>
public Hours hour { get; set; }
/// <summary>
/// Stundenliste ... für die Katz?
/// </summary>
public List<Hours> hours { get; set; }
/// <summary>
/// Liste der Stundeneinträge
/// </summary>
public List<DayTime> daytimes { get; set; }
/// <summary>
/// Einzelner Stundeneintrag
/// </summary>
public DayTime daytime { get; set; }
/// <summary>
/// Auch irgendwie doppelt ...
/// </summary>
public Operator operatorVar { get; set; }
public User user { get; set; }
public int error { get; set; }
public string message { get; set; }
}

View File

@@ -3,6 +3,7 @@ using CommunityToolkit.Mvvm.Input;
using Jugenddienst_Stunden.Models; using Jugenddienst_Stunden.Models;
using Jugenddienst_Stunden.Types; using Jugenddienst_Stunden.Types;
using System.Windows.Input; using System.Windows.Input;
using static System.Runtime.InteropServices.JavaScript.JSType;
namespace Jugenddienst_Stunden.ViewModels; namespace Jugenddienst_Stunden.ViewModels;
/// <summary> /// <summary>
@@ -14,7 +15,7 @@ public class StundeViewModel : ObservableObject, IQueryAttributable {
public string Title { get; set; } = "Eintrag bearbeiten"; public string Title { get; set; } = "Eintrag bearbeiten";
public string SubTitle { get; set; } = DateTime.Today.ToString("dddd, d. MMMM yyyy"); public string SubTitle { get; set; } = DateTime.Today.ToString("dddd, d. MMMM yyyy");
private HoursBase HoursBase = new HoursBase(); //private HoursBase HoursBase = new HoursBase();
internal Settings Settings = new Settings(); internal Settings Settings = new Settings();
public event EventHandler<string> AlertEvent; public event EventHandler<string> AlertEvent;
@@ -51,7 +52,8 @@ public class StundeViewModel : ObservableObject, IQueryAttributable {
if (_dayTime != value) { if (_dayTime != value) {
_dayTime = value; _dayTime = value;
}OnPropertyChanged(nameof(DayTime)); }
OnPropertyChanged(nameof(DayTime));
} }
} }
@@ -77,13 +79,14 @@ public class StundeViewModel : ObservableObject, IQueryAttributable {
//public ICommand LoadDataCommand { get; private set; } //public ICommand LoadDataCommand { get; private set; }
public StundeViewModel() { public StundeViewModel() {
DayTime = new DayTime(); DayTime = new DayTime();
SaveCommand = new AsyncRelayCommand(Save); SaveCommand = new AsyncRelayCommand(Save);
//DeleteCommand = new AsyncRelayCommand(Delete); //DeleteCommand = new AsyncRelayCommand(Delete);
DeleteConfirmCommand = new Command(async () => await DeleteConfirm()); DeleteConfirmCommand = new Command(async () => await DeleteConfirm());
LoadSettingsAsync(); //LoadSettingsAsync();
} }
public StundeViewModel(DayTime stunde) { public StundeViewModel(DayTime stunde) {
@@ -91,9 +94,11 @@ public class StundeViewModel : ObservableObject, IQueryAttributable {
SaveCommand = new AsyncRelayCommand(Save); SaveCommand = new AsyncRelayCommand(Save);
DeleteConfirmCommand = new AsyncRelayCommand(DeleteConfirm); DeleteConfirmCommand = new AsyncRelayCommand(DeleteConfirm);
LoadSettingsAsync(); //LoadSettingsAsync();
} }
private async void LoadSettingsAsync() { private async void LoadSettingsAsync() {
try { try {
@@ -105,7 +110,7 @@ public class StundeViewModel : ObservableObject, IQueryAttributable {
GemeindeAktivSet = Settings.GemeindeAktivSet; GemeindeAktivSet = Settings.GemeindeAktivSet;
ProjektAktivSet = Settings.ProjektAktivSet; ProjektAktivSet = Settings.ProjektAktivSet;
GlobalVar.Settings = Settings;
OnPropertyChanged(nameof(OptionsGemeinde)); OnPropertyChanged(nameof(OptionsGemeinde));
OnPropertyChanged(nameof(OptionsFreistellung)); OnPropertyChanged(nameof(OptionsFreistellung));
OnPropertyChanged(nameof(OptionsProjekt)); OnPropertyChanged(nameof(OptionsProjekt));
@@ -119,21 +124,12 @@ public class StundeViewModel : ObservableObject, IQueryAttributable {
}
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; bool exceptionOccurred = false;
try { try {
await Models.HoursBase.SaveEntry(DayTime); await HoursBase.SaveEntry(DayTime);
} catch (Exception e) { } catch (Exception e) {
AlertEvent?.Invoke(this, e.Message); AlertEvent?.Invoke(this, e.Message);
exceptionOccurred = true; exceptionOccurred = true;
@@ -148,7 +144,7 @@ public class StundeViewModel : ObservableObject, IQueryAttributable {
} }
private async Task Delete() { private async Task Delete() {
await Models.HoursBase.DeleteEntry(DayTime); await HoursBase.DeleteEntry(DayTime);
await Shell.Current.GoToAsync($"..?date={DayTime.Day.ToString("yyyy-MM-dd")}"); await Shell.Current.GoToAsync($"..?date={DayTime.Day.ToString("yyyy-MM-dd")}");
} }
@@ -157,9 +153,10 @@ public class StundeViewModel : ObservableObject, IQueryAttributable {
bool answer = await ConfirmEvent.Invoke("Achtung", "Löschen kann nicht ungeschehen gemacht werden. Fortfahren?"); bool answer = await ConfirmEvent.Invoke("Achtung", "Löschen kann nicht ungeschehen gemacht werden. Fortfahren?");
if (answer) { if (answer) {
//Löschen //Löschen
await Models.HoursBase.DeleteEntry(DayTime); await HoursBase.DeleteEntry(DayTime);
await Shell.Current.GoToAsync($"..?date={DayTime.Day.ToString("yyyy-MM-dd")}"); await Shell.Current.GoToAsync($"..?date={DayTime.Day.ToString("yyyy-MM-dd")}");
} else { //nicht Löschen } else {
//nicht Löschen
} }
} }
@@ -177,9 +174,28 @@ public class StundeViewModel : ObservableObject, IQueryAttributable {
if (query.ContainsKey("load")) { if (query.ContainsKey("load")) {
//DateTime heute = DateTime.Now; //DateTime heute = DateTime.Now;
_dayTime = await Models.HoursBase.LoadEntry(Convert.ToInt32(query["load"])); try {
//_dayTime = await HoursBase.LoadEntry(Convert.ToInt32(query["load"]));
BaseResponse dat = await HoursBase.LoadBase("id=" + Convert.ToInt32(query["load"]));
_dayTime = dat.daytime;
_dayTime.TimeSpanVon = dat.daytime.Begin.ToTimeSpan();
_dayTime.TimeSpanBis = dat.daytime.End.ToTimeSpan();
OptionsGemeinde = dat.settings.Gemeinden;
OptionsProjekt = dat.settings.Projekte;
OptionsFreistellung = dat.settings.Freistellungen;
GemeindeAktivSet = dat.settings.GemeindeAktivSet;
ProjektAktivSet = dat.settings.ProjektAktivSet;
GlobalVar.Settings = dat.settings;
} catch (Exception e) {
AlertEvent?.Invoke(this, e.Message);
}
if (System.String.IsNullOrEmpty(DayTime.Description)) { if (System.String.IsNullOrEmpty(DayTime.Description)) {
AlertEvent?.Invoke(this, "Eintrag hat keine Daten zurückgegeben"); AlertEvent?.Invoke(this, "Eintrag hat keinen Beschreibungstext");
} }
SubTitle = DayTime.Day.ToString("dddd, d. MMMM yyyy"); SubTitle = DayTime.Day.ToString("dddd, d. MMMM yyyy");
@@ -192,34 +208,50 @@ public class StundeViewModel : ObservableObject, IQueryAttributable {
FreistellungEnabled = !_dayTime.Approved; FreistellungEnabled = !_dayTime.Approved;
OnPropertyChanged(nameof(FreistellungEnabled));
OnPropertyChanged(nameof(DayTime));
OnPropertyChanged(nameof(SubTitle));
} }
if (query.ContainsKey("date")) { if (query.ContainsKey("date")) {
Title = "Neuer Eintrag"; Title = "Neuer Eintrag";
DateTime _date = DateTime.ParseExact((string)query["date"], "yyyy-MM-dd", System.Globalization.CultureInfo.InvariantCulture); DateTime _date = DateTime.ParseExact((string)query["date"], "yyyy-MM-dd", System.Globalization.CultureInfo.InvariantCulture);
//Bei neuem Eintrag die vorhandenen des gleichen Tages anzeigen //Bei neuem Eintrag die vorhandenen des gleichen Tages anzeigen
try { try {
DayTimes = await HoursBase.LoadDay(_date); //DayTimes = await HoursBase.LoadDay(_date);
BaseResponse dat = await HoursBase.LoadBase("date=" + _date.ToString("yyyy-MM-dd"));
DayTimes = dat.daytimes;
OptionsGemeinde = dat.settings.Gemeinden;
OptionsProjekt = dat.settings.Projekte;
OptionsFreistellung = dat.settings.Freistellungen;
GemeindeAktivSet = dat.settings.GemeindeAktivSet;
ProjektAktivSet = dat.settings.ProjektAktivSet;
GlobalVar.Settings = dat.settings;
} catch (Exception) { } catch (Exception) {
//Ein Tag ohne Einträge gibt eine Fehlermeldung, //Ein Tag ohne Einträge gibt eine Fehlermeldung,
//die soll aber ignoriert werden, weil beim Neueintrag ist das ja Wurscht //die soll aber ignoriert werden, weil beim Neueintrag ist das ja Wurscht
} //In dem Fall müssen die Settings aber nochmal geholt werden, weil die dann nicht geladen wurden
LoadSettingsAsync();
} finally {
DayTime.Day = _date; DayTime.Day = _date;
SubTitle = _date.ToString("dddd, d. MMMM yyyy"); SubTitle = _date.ToString("dddd, d. MMMM yyyy");
FreistellungEnabled = true;
_ = LoadData(); DayTime.EmployeeId = GlobalVar.EmployeeId;
OnPropertyChanged(nameof(Title));
OnPropertyChanged(nameof(SubTitle));
OnPropertyChanged(nameof(DayTimes));
} }
}
OnPropertyChanged(nameof(FreistellungEnabled));
OnPropertyChanged(nameof(DayTime));
OnPropertyChanged(nameof(DayTimes));
OnPropertyChanged(nameof(SubTitle));
OnPropertyChanged(nameof(Title));
OnPropertyChanged(nameof(OptionsGemeinde));
OnPropertyChanged(nameof(OptionsFreistellung));
OnPropertyChanged(nameof(OptionsProjekt));
OnPropertyChanged(nameof(GemeindeAktivSet));
OnPropertyChanged(nameof(ProjektAktivSet));
} }

View File

@@ -25,16 +25,13 @@ internal class StundenViewModel : ObservableObject, IQueryAttributable, INotifyP
public event EventHandler<string> AlertEvent; public event EventHandler<string> AlertEvent;
public event EventHandler<string> InfoEvent; public event EventHandler<string> InfoEvent;
private HoursBase HoursBase = new HoursBase(); //private HoursBase HoursBase = new HoursBase();
internal Settings Settings = new Settings(); internal Settings Settings = new Settings();
public TimeOnly Sollstunden { get; set; } public TimeOnly Sollstunden { get; set; }
private string _title = HoursBase.name + " " + HoursBase.surname;
public string Title { public string Title { get; set; } = GlobalVar.Name + " " + GlobalVar.Surname;
get => _title;
set => SetProperty(ref _title, value);
}
private Hours _hour; private Hours _hour;
public Hours Hours { public Hours Hours {
@@ -150,13 +147,15 @@ internal class StundenViewModel : ObservableObject, IQueryAttributable, INotifyP
private bool doContinue = true; private bool doContinue = true;
/// <summary> /// <summary>
/// CTOR /// CTOR
/// </summary> /// </summary>
public StundenViewModel() { public StundenViewModel() {
_hour = new Hours(); _hour = new Hours();
//LoadSettingsAsync(); //LoadSettingsAsync();
HoursBase.tokendata = new TokenData(HoursBase.apiKey); //HoursBase.tokendata = new TokenData(HoursBase.apiKey);
LoadDataCommand = new AsyncRelayCommand(LoadData); LoadDataCommand = new AsyncRelayCommand(LoadData);
NewEntryCommand = new AsyncRelayCommand(NewEntryAsync); NewEntryCommand = new AsyncRelayCommand(NewEntryAsync);
SelectEntryCommand = new AsyncRelayCommand<DayTime>(SelectEntryAsync); SelectEntryCommand = new AsyncRelayCommand<DayTime>(SelectEntryAsync);
@@ -167,6 +166,7 @@ internal class StundenViewModel : ObservableObject, IQueryAttributable, INotifyP
} }
private async Task LoadSettingsAsync() { private async Task LoadSettingsAsync() {
try { try {
Settings = await HoursBase.LoadSettings(); Settings = await HoursBase.LoadSettings();
@@ -226,15 +226,24 @@ internal class StundenViewModel : ObservableObject, IQueryAttributable, INotifyP
/// </summary> /// </summary>
public async Task LoadDay(DateTime date) { public async Task LoadDay(DateTime date) {
DayTotal = new TimeOnly(0); DayTotal = new TimeOnly(0);
await LoadSettingsAsync(); //await LoadSettingsAsync();
//if (doContinue) { //if (doContinue) {
try { try {
DayTimes = await HoursBase.LoadDay(date); //_dayTimes = await HoursBase.LoadDay(date);
BaseResponse dat = await HoursBase.LoadBase("date=" + date.ToString("yyyy-MM-dd"));
_dayTimes = dat.daytimes;
Settings = dat.settings;
GemeindeAktivSet = Settings.GemeindeAktivSet;
ProjektAktivSet = Settings.ProjektAktivSet;
OnPropertyChanged(nameof(GemeindeAktivSet));
OnPropertyChanged(nameof(ProjektAktivSet));
List<Sollstunden> _soll; List<Sollstunden> _soll;
TimeSpan span = TimeSpan.Zero; TimeSpan span = TimeSpan.Zero;
bool merker = false; bool merker = false;
foreach (DayTime dt in DayTimes) { foreach (DayTime dt in _dayTimes) {
span += dt.End - dt.Begin; span += dt.End - dt.Begin;
//Nachtstunden dazurechnen //Nachtstunden dazurechnen
if (dt.Night.Ticks > 0 && !merker) { if (dt.Night.Ticks > 0 && !merker) {
@@ -249,13 +258,13 @@ internal class StundenViewModel : ObservableObject, IQueryAttributable, INotifyP
} catch (Exception e) { } catch (Exception e) {
DayTimes = new List<DayTime>(); _dayTimes = new List<DayTime>();
//TODO: hier könnte auch ein Fehler kommen, dann wäre InfoEvent falsch. //TODO: hier könnte auch ein Fehler kommen, dann wäre InfoEvent falsch.
InfoEvent?.Invoke(this, e.Message); InfoEvent?.Invoke(this, e.Message);
} finally { } finally {
OnPropertyChanged(nameof(DayTotal)); OnPropertyChanged(nameof(DayTotal));
OnPropertyChanged(nameof(Sollstunden)); OnPropertyChanged(nameof(Sollstunden));
//OnPropertyChanged(nameof(DayTimes)); OnPropertyChanged(nameof(DayTimes));
} }
//} //}

View File

@@ -1,5 +1,6 @@
using Jugenddienst_Stunden.Models; using Jugenddienst_Stunden.Models;
using ZXing.Net.Maui; using ZXing.Net.Maui;
using Jugenddienst_Stunden.Types;
namespace Jugenddienst_Stunden.Views; namespace Jugenddienst_Stunden.Views;
@@ -11,7 +12,7 @@ public partial class LoginPage : ContentPage {
private DateTime _lastDetectionTime; private DateTime _lastDetectionTime;
private readonly TimeSpan _detectionInterval = TimeSpan.FromSeconds(5); private readonly TimeSpan _detectionInterval = TimeSpan.FromSeconds(5);
internal HoursBase HoursBase = new HoursBase();
/// <summary> /// <summary>
/// CTOR /// CTOR
@@ -19,11 +20,6 @@ public partial class LoginPage : ContentPage {
public LoginPage() { public LoginPage() {
InitializeComponent(); InitializeComponent();
//if (BindingContext is LoginViewModel vm) {
// vm.AlertEvent += Vm_AlertEvent;
// vm.InfoEvent += Vm_InfoEvent;
// vm.MsgEvent += Vm_MsgEvent;
//}
barcodeScannerView.Options = new BarcodeReaderOptions { barcodeScannerView.Options = new BarcodeReaderOptions {
Formats = BarcodeFormat.QrCode, Formats = BarcodeFormat.QrCode,
@@ -31,6 +27,11 @@ public partial class LoginPage : ContentPage {
Multiple = false Multiple = false
}; };
//if (BindingContext is LoginViewModel vm) {
// vm.AlertEvent += Vm_AlertEvent;
// vm.InfoEvent += Vm_InfoEvent;
// vm.MsgEvent += Vm_MsgEvent;
//}
} }
@@ -41,30 +42,32 @@ public partial class LoginPage : ContentPage {
if ((currentTime - _lastDetectionTime) > _detectionInterval) { if ((currentTime - _lastDetectionTime) > _detectionInterval) {
_lastDetectionTime = currentTime; _lastDetectionTime = currentTime;
foreach (var barcode in e.Results) { foreach (var barcode in e.Results) {
if (HoursBase.apiKey != barcode.Value) { if (GlobalVar.ApiKey != barcode.Value) {
_ = MainThread.InvokeOnMainThreadAsync(async () => { _ = MainThread.InvokeOnMainThreadAsync(async () => {
//await DisplayAlert("Barcode erkannt", $"Barcode: {barcode.Format} - {barcode.Value}", "OK"); //await DisplayAlert("Barcode erkannt", $"Barcode: {barcode.Format} - {barcode.Value}", "OK");
try { try {
var tokendata = new TokenData(barcode.Value); var tokendata = new TokenData(barcode.Value);
HoursBase.tokendata = tokendata; GlobalVar.ApiUrl = tokendata.Url;
User user = await HoursBase.LoadUser(barcode.Value);
var op = await HoursBase.LoadOperator(barcode.Value); GlobalVar.ApiKey = barcode.Value;
HoursBase.apiKey = barcode.Value; GlobalVar.Name = user.Name;
HoursBase.name = op.name; GlobalVar.Surname = user.Surname;
HoursBase.surname = op.surname; GlobalVar.EmployeeId = user.Id;
HoursBase.EmployeeId = int.Parse(op.id);
Title = op.name + " " + op.surname; Title = user.Name + " " + user.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("apiKey", barcode.Value);
Preferences.Default.Set("name", op.name); //Preferences.Default.Set("name", op.name);
Preferences.Default.Set("surname", op.surname); //Preferences.Default.Set("surname", op.surname);
Preferences.Default.Set("EmployeeId", int.Parse(op.id)); //Preferences.Default.Set("EmployeeId", int.Parse(op.id));
await DisplayAlert("Login erfolgreich", op.name + " " + op.surname, "OK"); await DisplayAlert("Login erfolgreich", user.Name + " " + user.Surname, "OK");
if (Navigation.NavigationStack.Count > 1) if (Navigation.NavigationStack.Count > 1)
await Navigation.PopAsync(); await Navigation.PopAsync();
} catch (Exception e) { } catch (Exception e) {
await DisplayAlert("Fehler", e.Message, "OK"); await DisplayAlert("Fehler", e.Message, "OK");
} }
@@ -118,21 +121,16 @@ public partial class LoginPage : ContentPage {
try { try {
Types.User response = await BaseFunc.AuthUserPass(username, password, server); Types.User response = await BaseFunc.AuthUserPass(username, password, server);
var tokendata = new TokenData(response.Token); GlobalVar.ApiKey = response.Token;
var op = await HoursBase.LoadOperator(response.Token); GlobalVar.Name = response.Name;
HoursBase.apiKey = response.Token; GlobalVar.Surname = response.Surname;
HoursBase.name = op.name; GlobalVar.EmployeeId = response.Id;
HoursBase.surname = op.surname; GlobalVar.ApiUrl = server;
HoursBase.EmployeeId = int.Parse(op.id);
Title = op.name + " " + op.surname;
ServerLabel.Text = "Server: " + tokendata.Url.Replace("/appapi", "").Replace("https://", "").Replace("http://", "");
Preferences.Default.Set("apiKey", response.Token); Title = response.Name + " " + response.Surname;
Preferences.Default.Set("name", op.name); ServerLabel.Text = "Server: " + server.Replace("/appapi", "").Replace("https://", "").Replace("http://", "");
Preferences.Default.Set("surname", op.surname);
Preferences.Default.Set("EmployeeId", int.Parse(op.id));
await DisplayAlert("Login erfolgreich", op.name + " " + op.surname, "OK"); await DisplayAlert("Login erfolgreich", response.Name + " " + response.Surname, "OK");
if (Navigation.NavigationStack.Count > 1) if (Navigation.NavigationStack.Count > 1)
await Navigation.PopAsync(); await Navigation.PopAsync();
} catch (Exception ex) { } catch (Exception ex) {

View File

@@ -19,6 +19,7 @@ public partial class StundePage : ContentPage {
} }
private void Vm_AlertEvent(object? sender, string e) { private void Vm_AlertEvent(object? sender, string e) {
DisplayAlert("Fehler:", e, "OK"); DisplayAlert("Fehler:", e, "OK");
} }

View File

@@ -1,4 +1,5 @@
using Jugenddienst_Stunden.ViewModels; using Jugenddienst_Stunden.ViewModels;
using Jugenddienst_Stunden.Models;
namespace Jugenddienst_Stunden.Views; namespace Jugenddienst_Stunden.Views;
@@ -9,11 +10,14 @@ public partial class StundenPage : ContentPage {
private int heightValue; private int heightValue;
/// <summary> /// <summary>
/// CTOR /// CTOR
/// </summary> /// </summary>
public StundenPage() { public StundenPage() {
InitializeComponent(); InitializeComponent();
if (BindingContext is StundenViewModel vm) { if (BindingContext is StundenViewModel vm) {
vm.AlertEvent += Vm_AlertEvent; vm.AlertEvent += Vm_AlertEvent;
vm.InfoEvent += Vm_InfoEvent; vm.InfoEvent += Vm_InfoEvent;
@@ -21,13 +25,6 @@ public partial class StundenPage : ContentPage {
if (!CheckLogin()) { if (!CheckLogin()) {
NavigateToTargetPage(); NavigateToTargetPage();
} }
//// Bildschirmh<6D>he abrufen
//var screenHeight = DeviceDisplay.MainDisplayInfo.Height / DeviceDisplay.MainDisplayInfo.Density;
//// Berechnen der gew<65>nschten H<>he
//var desiredHeight = screenHeight - 450; // Abz<62>glich der Stunden<65>bersicht
//stundeItems.HeightRequest = desiredHeight;
#if ANDROID #if ANDROID
heightValue = 280; heightValue = 280;
#elif IOS #elif IOS
@@ -41,6 +38,9 @@ public partial class StundenPage : ContentPage {
SizeChanged += OnPageSizeChanged; SizeChanged += OnPageSizeChanged;
} }
private void Vm_AlertEvent(object? sender, string e) { private void Vm_AlertEvent(object? sender, string e) {
MainThread.BeginInvokeOnMainThread(async () => { MainThread.BeginInvokeOnMainThread(async () => {
await DisplayAlert("Fehler:", e, "OK"); await DisplayAlert("Fehler:", e, "OK");
@@ -64,6 +64,8 @@ public partial class StundenPage : ContentPage {
return Preferences.Default.Get("apiKey", "") != ""; return Preferences.Default.Get("apiKey", "") != "";
} }
private async void NavigateToTargetPage() { private async void NavigateToTargetPage() {
await Navigation.PushAsync(new LoginPage()); await Navigation.PushAsync(new LoginPage());
} }