diff --git a/Jugenddienst Stunden/Models/Auth.cs b/Jugenddienst Stunden/Models/Auth.cs index f7d74b2..d9079f2 100644 --- a/Jugenddienst Stunden/Models/Auth.cs +++ b/Jugenddienst Stunden/Models/Auth.cs @@ -37,11 +37,6 @@ class Auth { /// /// Stundeneintrag speichern /// - /// - /// - /// - /// - /// public static async Task SaveItemAsync(string url, string token, DayTime item, bool isNewItem = false) { //using (HttpClient client = new HttpClient() { Timeout = TimeSpan.FromSeconds(15) }) { diff --git a/Jugenddienst Stunden/Models/Stunde.cs b/Jugenddienst Stunden/Models/Stunde.cs index 249aa53..75372cb 100644 --- a/Jugenddienst Stunden/Models/Stunde.cs +++ b/Jugenddienst Stunden/Models/Stunde.cs @@ -10,7 +10,6 @@ internal class Stunde : ObservableObject { public DateTime Date { get; set; } - //Default-Werte zum Testen 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", ""); @@ -21,8 +20,6 @@ internal class Stunde : ObservableObject { public static async Task LoadData() { - - if (string.IsNullOrEmpty(apiKey)) { throw new Exception("Kein APIKEY, bitte zuerst Login durchführen"); } @@ -31,9 +28,6 @@ internal class Stunde : ObservableObject { if (Connectivity.Current.NetworkAccess == NetworkAccess.None) { throw new Exception("Bitte überprüfen Sie Ihre Internetverbindung und versuchen Sie es erneut."); - //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); @@ -56,20 +50,51 @@ internal class Stunde : ObservableObject { return hours; } - /// - /// Basisdaten: Mitarbeiterdaten, Projekte, Gemeinden, Freistellungen. - /// - /// - /// - public static async Task LoadBasicData() { + /// + /// Einstellungen + /// + public static async Task LoadSettings() + { + + Settings settings; + + if (Connectivity.Current.NetworkAccess == NetworkAccess.None) + { + throw new Exception("Bitte überprüfen Sie Ihre Internetverbindung und versuchen Sie es erneut."); + } + else + { + var tokendata = new TokenData(apiKey); + + string? data = await Auth.GetApiDataWithAuthAsync(tokendata.url + "?settings", tokendata.apiKey); + + if (data == "null") + { + throw new Exception("Keine Daten erhalten"); + } + if (data == "\"Lalala\"") + { + throw new Exception("Problem mit Token"); + } + if (data == null) + { + throw new Exception("Keine Daten erhalten"); + } + settings = JsonConvert.DeserializeObject(data) ?? throw new Exception("Fehler beim Deserialisieren der Daten"); + + } + return settings; + } + + /// + /// Basisdaten: Mitarbeiterdaten, Projekte, Gemeinden, Freistellungen. + /// + public static async Task LoadBasicData() { Hours hours = new Hours(); if (Connectivity.Current.NetworkAccess == NetworkAccess.None) { throw new Exception("Bitte überprüfen Sie Ihre Internetverbindung und versuchen Sie es erneut."); - //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); @@ -94,9 +119,6 @@ internal class Stunde : ObservableObject { /// /// Zeiten eines Tages holen /// - /// - /// - /// public static async Task> LoadDay(DateTime date) { if (string.IsNullOrEmpty(apiKey)) { throw new Exception("Kein APIKEY, bitte zuerst Login durchführen"); @@ -104,9 +126,6 @@ internal class Stunde : ObservableObject { if (Connectivity.Current.NetworkAccess == NetworkAccess.None) { throw new Exception("Bitte überprüfen Sie Ihre Internetverbindung und versuchen Sie es erneut."); - //await App.Current.MainPage.DisplayAlert("Keine Internetverbindung", - // "Bitte überprüfen Sie Ihre Internetverbindung und versuchen Sie es erneut.", - // "OK"); } var tokendata = new TokenData(apiKey); @@ -134,8 +153,6 @@ internal class Stunde : ObservableObject { /// /// Einzelnen Stundeneintrag holen /// - /// - /// public static async Task LoadEntry(int id) { var tokendata = new TokenData(apiKey); @@ -171,8 +188,6 @@ internal class Stunde : ObservableObject { /// /// Eintrag speichern /// - /// - /// public static async Task SaveEntry(DayTime stunde) { //, string begin, string end, string freistellung, string bemerkung) { var tokendata = new TokenData(apiKey); @@ -187,14 +202,9 @@ internal class Stunde : ObservableObject { /// /// Eintrag löschen /// - /// - /// - public static async Task DeleteEntry(DayTime stunde) { //, string begin, string end, string freistellung, string bemerkung) { - + public static async Task DeleteEntry(DayTime stunde) { var tokendata = new TokenData(apiKey); await Auth.DeleteItemAsync(tokendata.url + "/entry/" + stunde.id, tokendata.apiKey); - - return stunde; } diff --git a/Jugenddienst Stunden/Types/DayTime.cs b/Jugenddienst Stunden/Types/DayTime.cs index 845c5dc..6151979 100644 --- a/Jugenddienst Stunden/Types/DayTime.cs +++ b/Jugenddienst Stunden/Types/DayTime.cs @@ -4,103 +4,107 @@ namespace Jugenddienst_Stunden.Types; /// /// Represents a day time entry for an employee. /// -public class DayTime { - /// - /// ID des Stundeneintrages - /// - public int? id { get; set; } +public class DayTime +{ + /// + /// ID des Stundeneintrages + /// + public int? id { get; set; } - /// - /// Mitarbeiter-ID - /// - public int EmployeeId { get; set; } + /// + /// Mitarbeiter-ID + /// + public int EmployeeId { get; set; } - /// - /// Der betreffende Tag - /// - public DateTime day { get; set; } + /// + /// Der betreffende Tag + /// + public DateTime day { get; set; } - /// - /// Der Wochentag - /// - public int wday { get; set; } + /// + /// Der Wochentag + /// + public int wday { get; set; } - /// - /// Arbeitsbeginn - /// - public TimeOnly begin { get; set; } + /// + /// Arbeitsbeginn + /// + public TimeOnly begin { get; set; } - /// - /// Arbeitsende - /// - public TimeOnly end { get; set; } + /// + /// Arbeitsende + /// + public TimeOnly end { get; set; } - /// - /// Beschreibung der Arbeit - /// - public string description { get; set; } + /// + /// Beschreibung der Arbeit + /// + public string description { get; set; } - /// - /// Freistellung - /// - public string? free { get; set; } + /// + /// Freistellung + /// + public string? free { get; set; } - /// - /// Freisetellung genehmigt? - /// - public bool? approved { get; set; } + /// + /// Freisetellung genehmigt? + /// + public bool? approved { get; set; } - /// - /// Sollte nix sein - /// - public int? type { get; set; } + /// + /// Sollte nix sein + /// + public int? type { get; set; } - /// - /// Das gewählte Projekt - /// - public int? projekt { get; set; } + /// + /// Das gewählte Projekt + /// + public int? projekt { get; set; } - /// - /// Die gewählte Gemeinde - /// - public int? gemeinde { get; set; } + /// + /// Die gewählte Gemeinde + /// + public int? gemeinde { get; set; } - /// - /// Nachtstunden - /// - public TimeOnly night { get; set; } + /// + /// Nachtstunden + /// + public TimeOnly night { get; set; } - /// - /// Summe Arbeitszeit (inklusive Nachstunden mit Faktor) - /// - public Dictionary total { get; set; } - public TimeOnly end_print { get; set; } - public TimeSpan TimeSpanVon { get; set; } - public TimeSpan TimeSpanBis { get; set; } + /// + /// Summe Arbeitszeit (inklusive Nachstunden mit Faktor) + /// + public Dictionary total { get; set; } + public TimeOnly end_print { get; set; } + public TimeSpan TimeSpanVon { get; set; } + public TimeSpan TimeSpanBis { get; set; } - /// - /// Projekte für die Auswahlliste - /// - public Collection Projekte { get; set; } + /// + /// Projekte für die Auswahlliste + /// + public Collection Projekte { get; set; } - /// - /// Gemeinden für die Auswahlliste - /// - public Collection Gemeinden { get; set; } - public Collection Freistellungen { get; set; } + /// + /// Gemeinden für die Auswahlliste + /// + public Collection Gemeinden { get; set; } + public Collection Freistellungen { get; set; } - /// - /// Gets the active Gemeinde based on the gemeinde ID. - /// - public Gemeinde GemeindeAktiv { get; set; } + /// + /// Gets the active Gemeinde based on the gemeinde ID. + /// + public Gemeinde GemeindeAktiv { get; set; } - /// - /// Gets the active Projekt based on the projekt ID. - /// - public Projekt ProjektAktiv { get; set; } + /// + /// Gets the active Projekt based on the projekt ID. + /// + public Projekt ProjektAktiv { get; set; } - /// - /// Gets the active Freistellung based on the Freistellung ID - /// - public Freistellung FreistellungAktiv { get; set; } + /// + /// Gets the active Freistellung based on the Freistellung ID + /// + public Freistellung FreistellungAktiv { get; set; } + + public bool ProjektAktivSet { get; set; } = false; + public bool GemeindeAktivSet { get; set; } = false; } diff --git a/Jugenddienst Stunden/Types/Settings.cs b/Jugenddienst Stunden/Types/Settings.cs new file mode 100644 index 0000000..2860de3 --- /dev/null +++ b/Jugenddienst Stunden/Types/Settings.cs @@ -0,0 +1,15 @@ +using System.Collections.ObjectModel; + +namespace Jugenddienst_Stunden.Types; + +/// +/// Einstellungen +/// +public class Settings +{ + public bool ProjektAktivSet { get; set; } + public bool GemeindeAktivSet { get; set; } + public Collection Projekte { get; set; } + public Collection Gemeinden { get; set; } + public Collection Freistellungen { get; set; } +} diff --git a/Jugenddienst Stunden/ViewModels/StundeViewModel.cs b/Jugenddienst Stunden/ViewModels/StundeViewModel.cs index 466b56d..ba6f875 100644 --- a/Jugenddienst Stunden/ViewModels/StundeViewModel.cs +++ b/Jugenddienst Stunden/ViewModels/StundeViewModel.cs @@ -6,197 +6,263 @@ using System.Windows.Input; using static System.Runtime.InteropServices.JavaScript.JSType; 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. MMMM yyyy"); + public string SubTitle { get; set; } = DateTime.Today.ToString("dddd, d. MMMM yyyy"); + + private Settings _settings; + public Settings Settings + { + get => _settings; set + { + if (_settings != value) + { + _settings = value; + } + } + } + + private DayTime _stunde; + public DayTime Stunde + { + get => _stunde; + set + { + if (_stunde != value) + { + _stunde = value; + OnPropertyChanged(nameof(Stunde)); + } + } + } + + public string Title { get; set; } = "Eintrag bearbeiten"; + + public event EventHandler AlertEvent; + public event EventHandler InfoEvent; + public event Func> ConfirmEvent; - private DayTime _stunde; - public DayTime Stunde { get => _stunde; } + public ObservableCollection OptionsGemeinde { get; private set; } + public ObservableCollection OptionsProjekt { get; private set; } + public ObservableCollection OptionsFreistellung { get; private set; } + public ObservableCollection DayTimes { get; set; } - public string Title { get; set; } = "Eintrag bearbeiten"; + //private Gemeinde _selectedGemeinde; + public Gemeinde SelectedOptionGemeinde + { + get => _stunde.GemeindeAktiv; + set + { + if (_stunde.GemeindeAktiv != value) + { + //_selectedGemeinde = value; + _stunde.GemeindeAktiv = value; + OnPropertyChanged(nameof(SelectedOptionGemeinde)); + } + } + } - public event EventHandler AlertEvent; - public event EventHandler InfoEvent; - public event Func> ConfirmEvent; + //private Projekt _selectedProjekt; + public Projekt SelectedOptionProjekt + { + get => _stunde.ProjektAktiv; + set + { + if (_stunde.ProjektAktiv != value) + { + //_selectedProjekt = value; + _stunde.ProjektAktiv = value; + OnPropertyChanged(nameof(SelectedOptionProjekt)); + } + } + } - - public ObservableCollection OptionsGemeinde { get; private set; } - public ObservableCollection OptionsProjekt { get; private set; } - public ObservableCollection OptionsFreistellung { get; private set; } - public ObservableCollection DayTimes { get; set; } - - //private Gemeinde _selectedGemeinde; - public Gemeinde SelectedOptionGemeinde { - get => _stunde.GemeindeAktiv; - set { - if (_stunde.GemeindeAktiv != value) { - //_selectedGemeinde = value; - _stunde.GemeindeAktiv = value; - OnPropertyChanged(nameof(SelectedOptionGemeinde)); - } - } - } - - //private Projekt _selectedProjekt; - public Projekt SelectedOptionProjekt { - get => _stunde.ProjektAktiv; - set { - if (_stunde.ProjektAktiv != value) { - //_selectedProjekt = value; - _stunde.ProjektAktiv = value; - OnPropertyChanged(nameof(SelectedOptionProjekt)); - } - } - } - - //private Freistellung _selectedFreistellung; - public Freistellung SelectedOptionFreistellung { - get => _stunde.FreistellungAktiv; - set { - if (_stunde.FreistellungAktiv != value) { - _stunde.FreistellungAktiv = value; - OnPropertyChanged(nameof(SelectedOptionFreistellung)); - } - } - } - - - - - public ICommand SaveCommand { get; private set; } - public ICommand DeleteCommand { get; private set; } - public ICommand DeleteConfirmCommand { get; private set; } - //public ICommand LoadDataCommand { get; private set; } - - - public StundeViewModel() { - _stunde = new DayTime(); - - SaveCommand = new AsyncRelayCommand(Save); - //DeleteCommand = new AsyncRelayCommand(Delete); - DeleteConfirmCommand = new Command(async () => await DeleteConfirm()); - - } - - public StundeViewModel(DayTime stunde) { - _stunde = stunde; - - SaveCommand = new AsyncRelayCommand(Save); - DeleteConfirmCommand = new AsyncRelayCommand(DeleteConfirm); - } - - private async Task LoadData() { - try { - Hours _hours = await Models.Stunde.LoadBasicData(); - OptionsProjekt = new ObservableCollection(_hours.Projekte); - OptionsGemeinde = new ObservableCollection(_hours.Gemeinden); - OptionsFreistellung = new ObservableCollection(_hours.Freistellungen); - OnPropertyChanged(nameof(OptionsGemeinde)); - OnPropertyChanged(nameof(OptionsProjekt)); - OnPropertyChanged(nameof(OptionsFreistellung)); - _stunde.EmployeeId = _hours.EmployeeId; - } catch (Exception e) { - AlertEvent?.Invoke(this, e.Message); - } - } - - async Task Save() { - bool exceptionOccurred = false; - try { - await Models.Stunde.SaveEntry(_stunde); - } catch (Exception e) { - AlertEvent?.Invoke(this, e.Message); - exceptionOccurred = true; - } - if (!exceptionOccurred) { - if (_stunde.id != null) { - await Shell.Current.GoToAsync($"..?saved={_stunde.id}"); - } else { - await Shell.Current.GoToAsync($"..?date={_stunde.day.ToString("yyyy-MM-dd")}"); - } - } - } - - private async Task Delete() { - await Models.Stunde.DeleteEntry(_stunde); - await Shell.Current.GoToAsync($"..?date={_stunde.day.ToString("yyyy-MM-dd")}"); - } - - private async Task DeleteConfirm() { - if (ConfirmEvent != null) { - bool answer = await ConfirmEvent.Invoke("Achtung", "Löschen kann nicht ungeschehen gemacht werden. Fortfahren?"); - if (answer) { - //Löschen - await Models.Stunde.DeleteEntry(_stunde); - await Shell.Current.GoToAsync($"..?date={_stunde.day.ToString("yyyy-MM-dd")}"); - } else { //nicht Löschen - } - } - - } + //private Freistellung _selectedFreistellung; + public Freistellung SelectedOptionFreistellung + { + get => _stunde.FreistellungAktiv; + set + { + if (_stunde.FreistellungAktiv != value) + { + _stunde.FreistellungAktiv = value; + OnPropertyChanged(nameof(SelectedOptionFreistellung)); + } + } + } - async void IQueryAttributable.ApplyQueryAttributes(IDictionary query) { - var probe = query; - if (query.ContainsKey("load")) { + public ICommand SaveCommand { get; private set; } + public ICommand DeleteCommand { get; private set; } + public ICommand DeleteConfirmCommand { get; private set; } + //public ICommand LoadDataCommand { get; private set; } - //DateTime heute = DateTime.Now; - _stunde = await Models.Stunde.LoadEntry(Convert.ToInt32(query["load"])); - if (System.String.IsNullOrEmpty(_stunde.description)) { - AlertEvent?.Invoke(this, "Eintrag hat keine Daten zurückgegeben"); - } - SubTitle = _stunde.day.ToString("dddd, d. MMMM yyyy"); - OptionsProjekt = new ObservableCollection(_stunde.Projekte); - OptionsGemeinde = new ObservableCollection(_stunde.Gemeinden); - OptionsFreistellung = new ObservableCollection(_stunde.Freistellungen); - OnPropertyChanged(nameof(OptionsGemeinde)); - OnPropertyChanged(nameof(OptionsProjekt)); - OnPropertyChanged(nameof(OptionsFreistellung)); + public StundeViewModel() + { + _stunde = new DayTime(); - //OptionsProjekt.FirstOrDefault(x => x.Id == _stunde.projekt); + SaveCommand = new AsyncRelayCommand(Save); + //DeleteCommand = new AsyncRelayCommand(Delete); + DeleteConfirmCommand = new Command(async () => await DeleteConfirm()); - 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)); + public StundeViewModel(DayTime stunde) + { + _stunde = stunde; - SelectedOptionFreistellung = OptionsFreistellung.FirstOrDefault(Freistellung => Freistellung.Id == _stunde.free) ?? new Freistellung(); - OnPropertyChanged(nameof(SelectedOptionFreistellung)); + SaveCommand = new AsyncRelayCommand(Save); + DeleteConfirmCommand = new AsyncRelayCommand(DeleteConfirm); + } - OnPropertyChanged(nameof(Stunde)); - OnPropertyChanged(nameof(SubTitle)); + private async Task LoadData() + { + try + { + Hours _hours = await Models.Stunde.LoadBasicData(); + OptionsProjekt = new ObservableCollection(_hours.Projekte); + OptionsGemeinde = new ObservableCollection(_hours.Gemeinden); + OptionsFreistellung = new ObservableCollection(_hours.Freistellungen); + OnPropertyChanged(nameof(OptionsGemeinde)); + OnPropertyChanged(nameof(OptionsProjekt)); + OnPropertyChanged(nameof(OptionsFreistellung)); + _stunde.EmployeeId = _hours.EmployeeId; + } + catch (Exception e) + { + AlertEvent?.Invoke(this, e.Message); + } + } - } - if (query.ContainsKey("date")) { - Title = "Neuer Eintrag"; + async Task Save() + { + bool exceptionOccurred = false; + try + { + await Models.Stunde.SaveEntry(_stunde); + } + catch (Exception e) + { + AlertEvent?.Invoke(this, e.Message); + exceptionOccurred = true; + } + if (!exceptionOccurred) + { + if (_stunde.id != null) + { + await Shell.Current.GoToAsync($"..?saved={_stunde.id}"); + } + else + { + await Shell.Current.GoToAsync($"..?date={_stunde.day.ToString("yyyy-MM-dd")}"); + } + } + } - DateTime _date = DateTime.ParseExact((string)query["date"], "yyyy-MM-dd", System.Globalization.CultureInfo.InvariantCulture); + private async Task Delete() + { + await Models.Stunde.DeleteEntry(_stunde); + await Shell.Current.GoToAsync($"..?date={_stunde.day.ToString("yyyy-MM-dd")}"); + } - //Bei neuem Eintrag die vorhandenen des gleichen Tages anzeigen - try { - DayTimes = await Models.Stunde.LoadDay(_date); - } catch (Exception) { - //Ein Tag ohne Einträge gibt eine Fehlermeldung, - //die soll aber ignoriert werden, weil beim Neueintrag ist das ja Wurscht - } + private async Task DeleteConfirm() + { + if (ConfirmEvent != null) + { + bool answer = await ConfirmEvent.Invoke("Achtung", "Löschen kann nicht ungeschehen gemacht werden. Fortfahren?"); + if (answer) + { + //Löschen + await Models.Stunde.DeleteEntry(_stunde); + await Shell.Current.GoToAsync($"..?date={_stunde.day.ToString("yyyy-MM-dd")}"); + } + else + { //nicht Löschen + } + } - _stunde.day = _date; - SubTitle = _date.ToString("dddd, d. MMMM yyyy"); + } - _ = LoadData(); - OnPropertyChanged(nameof(Title)); - OnPropertyChanged(nameof(SubTitle)); - OnPropertyChanged(nameof(DayTimes)); - } - } + private async Task LoadSettings() + { + Settings = await Models.Stunde.LoadSettings(); + } + + /// + /// Anwenden der Query-Parameter + /// + async void IQueryAttributable.ApplyQueryAttributes(IDictionary query) + { + await LoadSettings(); + var probe = query; + if (query.ContainsKey("load")) + { + + //DateTime heute = DateTime.Now; + Stunde = await Models.Stunde.LoadEntry(Convert.ToInt32(query["load"])); + if (System.String.IsNullOrEmpty(Stunde.description)) + { + AlertEvent?.Invoke(this, "Eintrag hat keine Daten zurückgegeben"); + } + SubTitle = Stunde.day.ToString("dddd, d. MMMM yyyy"); + + OptionsProjekt = new ObservableCollection(Stunde.Projekte); + OptionsGemeinde = new ObservableCollection(Stunde.Gemeinden); + OptionsFreistellung = new ObservableCollection(Stunde.Freistellungen); + OnPropertyChanged(nameof(OptionsGemeinde)); + OnPropertyChanged(nameof(OptionsProjekt)); + OnPropertyChanged(nameof(OptionsFreistellung)); + + //OptionsProjekt.FirstOrDefault(x => x.Id == _stunde.projekt); + + 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(SubTitle)); + + } + if (query.ContainsKey("date")) + { + Title = "Neuer Eintrag"; + + DateTime _date = DateTime.ParseExact((string)query["date"], "yyyy-MM-dd", System.Globalization.CultureInfo.InvariantCulture); + + //Bei neuem Eintrag die vorhandenen des gleichen Tages anzeigen + try + { + DayTimes = await Models.Stunde.LoadDay(_date); + } + catch (Exception) + { + //Ein Tag ohne Einträge gibt eine Fehlermeldung, + //die soll aber ignoriert werden, weil beim Neueintrag ist das ja Wurscht + } + + _stunde.day = _date; + SubTitle = _date.ToString("dddd, d. MMMM yyyy"); + + _ = LoadData(); + OnPropertyChanged(nameof(Title)); + OnPropertyChanged(nameof(SubTitle)); + OnPropertyChanged(nameof(DayTimes)); + } + + } } diff --git a/Jugenddienst Stunden/ViewModels/StundenViewModel.cs b/Jugenddienst Stunden/ViewModels/StundenViewModel.cs index 3fb043e..9ace248 100644 --- a/Jugenddienst Stunden/ViewModels/StundenViewModel.cs +++ b/Jugenddienst Stunden/ViewModels/StundenViewModel.cs @@ -5,34 +5,41 @@ using Newtonsoft.Json.Linq; using System.Collections.ObjectModel; using System.ComponentModel; using System.Runtime.CompilerServices; +using System.Threading.Tasks; using System.Windows.Input; namespace Jugenddienst_Stunden.ViewModels; -internal class StundenViewModel : ObservableObject, IQueryAttributable, INotifyPropertyChanged { - public string Name => AppInfo.Name; - public string Surname => AppInfo.VersionString; - public string MoreInfoUrl => "https://aka.ms/maui"; - public string Message => "Hier werden deine geleisteten Arbeitsstunden aufgelistet"; - public string LoadOverview => "Lade Summen für " + DateTime.Today.ToString("MMMM"); - //public static DateTime GetDay = DateTime.Today; - //public string ShowDay => "Zeit an Tag " + GetDay.ToString("ddd d. MMM") + ": "; +internal class StundenViewModel : ObservableObject, IQueryAttributable, INotifyPropertyChanged +{ + public string Name => AppInfo.Name; + public string Surname => AppInfo.VersionString; + public string MoreInfoUrl => "https://aka.ms/maui"; + public string Message => "Hier werden deine geleisteten Arbeitsstunden aufgelistet"; + public string LoadOverview => "Lade Summen für " + DateTime.Today.ToString("MMMM"); + //public static DateTime GetDay = DateTime.Today; + //public string ShowDay => "Zeit an Tag " + GetDay.ToString("ddd d. MMM") + ": "; - public ICommand NewEntryCommand { get; } - public ICommand SelectEntryCommand { get; } - public ICommand LoadDataCommand { get; private set; } - public ICommand LoadDayCommand { get; private set; } - public ICommand RefreshListCommand { get; } + public ICommand NewEntryCommand { get; } + public ICommand SelectEntryCommand { get; } + public ICommand LoadDataCommand { get; private set; } + public ICommand LoadDayCommand { get; private set; } + public ICommand RefreshListCommand { get; } public ICommand RefreshCommand { get; } public event EventHandler AlertEvent; - public event EventHandler InfoEvent; + public event EventHandler InfoEvent; + + private Settings Settings { get; set; } private bool isRefreshing; - public bool IsRefreshing { + public bool IsRefreshing + { get => isRefreshing; - set { - if (isRefreshing != value) { + set + { + if (isRefreshing != value) + { isRefreshing = value; OnPropertyChanged(); } @@ -40,203 +47,243 @@ internal class StundenViewModel : ObservableObject, IQueryAttributable, INotifyP } private string _title = Preferences.Default.Get("name", "") + " " + Preferences.Default.Get("surname", ""); - public string Title { - get => _title; - set => SetProperty(ref _title, value); - } + public string Title + { + get => _title; + set => SetProperty(ref _title, value); + } - private Hours _hour; - public Hours Hours { - get => _hour; - } + private Hours _hour; + public Hours Hours + { + get => _hour; + } - /// - /// Gesamtstunden an einem Tag - /// - public TimeOnly DayTotal { get; set; } + /// + /// Gesamtstunden an einem Tag + /// + public TimeOnly DayTotal { get; set; } - /// - /// Liste der Tageszeiten - /// - private ObservableCollection _dayTimes = new ObservableCollection(); - public ObservableCollection DayTimes { - get => _dayTimes; - set => SetProperty(ref _dayTimes, value); - } + /// + /// Liste der Tageszeiten + /// + private ObservableCollection _dayTimes = new ObservableCollection(); + public ObservableCollection DayTimes + { + get => _dayTimes; + set => SetProperty(ref _dayTimes, value); + } - /// - /// Mindest-Datum für den Datepicker - /// - public DateTime MinimumDate { - get => DateTime.Today.AddDays(-365); - } + /// + /// Mindest-Datum für den Datepicker + /// + public DateTime MinimumDate + { + get => DateTime.Today.AddDays(-365); + } - /// - /// Höchst-Datum für den Datepicker - /// - public DateTime MaximumDate { - get => DateTime.Today.AddDays(60); - } + /// + /// Höchst-Datum für den Datepicker + /// + public DateTime MaximumDate + { + get => DateTime.Today.AddDays(60); + } - /// - /// Heutiges Datum, wenn das Datum geändert wird, wird auch der Tag geladen - /// - private DateTime dateToday = DateTime.Today; - public DateTime DateToday { - get => dateToday; - set { - if (dateToday != value) { - dateToday = value; - //GetDay = value; - //OnPropertyChanged(); - Task.Run(() => LoadDay(value)); + /// + /// Heutiges Datum, wenn das Datum geändert wird, wird auch der Tag geladen + /// + private DateTime dateToday = DateTime.Today; + public DateTime DateToday + { + get => dateToday; + set + { + if (dateToday != value) + { + dateToday = value; + //GetDay = value; + //OnPropertyChanged(); + Task.Run(() => LoadDay(value)); } - } - } + } + } - /// - /// Monatsübersicht: Geleistete Stunden - /// - public string? ZeitCalculated { - get => _hour.zeit_total; - } + /// + /// Monatsübersicht: Geleistete Stunden + /// + public string? ZeitCalculated + { + get => _hour.zeit_total; + } - /// - /// Monatsübersicht: Sollstunden - /// - public string? Nominal { - get => _hour.nominal; - } + /// + /// Monatsübersicht: Sollstunden + /// + public string? Nominal + { + get => _hour.nominal; + } - /// - /// Monatsübersicht: Differenz zwischen Soll und geleisteten Stunden - /// - public string? Overtime { - get => _hour.overtime; - } + /// + /// Monatsübersicht: Differenz zwischen Soll und geleisteten Stunden + /// + public string? Overtime + { + get => _hour.overtime; + } - /// - /// Monatsübersicht: Restüberstunden insgesamt - /// - public string OvertimeMonth { - get => _hour.overtime_month; - } + /// + /// Monatsübersicht: Restüberstunden insgesamt + /// + public string OvertimeMonth + { + get => _hour.overtime_month; + } - /// - /// Monatsübersicht: Resturlaub - /// - public string Holiday { - get => _hour.holiday; - } - - + /// + /// Monatsübersicht: Resturlaub + /// + public string Holiday + { + get => _hour.holiday; + } - - /// - /// CTOR - /// - public StundenViewModel() { - _hour = new Types.Hours(); - LoadDataCommand = new AsyncRelayCommand(LoadData); - NewEntryCommand = new AsyncRelayCommand(NewEntryAsync); - SelectEntryCommand = new AsyncRelayCommand(SelectEntryAsync); - RefreshListCommand = new AsyncRelayCommand(RefreshList); + /// + /// CTOR + /// + public StundenViewModel() + { - Task task = LoadDay(DateTime.Today); + _hour = new Types.Hours(); + LoadDataCommand = new AsyncRelayCommand(LoadData); + NewEntryCommand = new AsyncRelayCommand(NewEntryAsync); + SelectEntryCommand = new AsyncRelayCommand(SelectEntryAsync); + RefreshListCommand = new AsyncRelayCommand(RefreshList); RefreshCommand = new Command(async () => await RefreshItemsAsync()); + Task task = LoadDay(DateTime.Today); + + + } - /// - /// Öffnet eine neue Stundeneingabe - /// - /// - private async Task NewEntryAsync() { - //Hier muss das Datum übergeben werden - //await Shell.Current.GoToAsync(nameof(Views.StundePage)); - await Shell.Current.GoToAsync($"{nameof(Views.StundePage)}?date={dateToday:yyyy-MM-dd}"); - } + /// + /// Öffnet eine neue Stundeneingabe + /// + /// + private async Task NewEntryAsync() + { + //Hier muss das Datum übergeben werden + //await Shell.Current.GoToAsync(nameof(Views.StundePage)); + await Shell.Current.GoToAsync($"{nameof(Views.StundePage)}?date={dateToday:yyyy-MM-dd}"); + } - /// - /// Öffnet eine bestehende Stundeneingabe - /// - /// - /// - private async Task SelectEntryAsync(DayTime entry) { - if (entry != null && entry.id != null) { - //var navigationParameters = new Dictionary { { "load", entry.id } }; - //await Shell.Current.GoToAsync($"{nameof(Views.StundePage)}", navigationParameters); - await Shell.Current.GoToAsync($"{nameof(Views.StundePage)}?load={entry.id}"); - } else AlertEvent?.Invoke(this, "Auswahl enthält keine Daten"); - } + /// + /// Öffnet eine bestehende Stundeneingabe + /// + /// + /// + private async Task SelectEntryAsync(DayTime entry) + { + if (entry != null && entry.id != null) + { + //var navigationParameters = new Dictionary { { "load", entry.id } }; + //await Shell.Current.GoToAsync($"{nameof(Views.StundePage)}", navigationParameters); + await Shell.Current.GoToAsync($"{nameof(Views.StundePage)}?load={entry.id}"); + } + else AlertEvent?.Invoke(this, "Auswahl enthält keine Daten"); + } - private async Task RefreshList() { - OnPropertyChanged(nameof(DayTimes)); - } + private async Task RefreshList() + { + OnPropertyChanged(nameof(DayTimes)); + } - /// - /// Lädt die Monatssummen für die Übersicht - /// - /// - private async Task LoadData() { - try { - _hour = await Models.Stunde.LoadData(); - RefreshProperties(); - } catch (Exception e) { - AlertEvent?.Invoke(this, e.Message); - } - } + /// + /// Lädt die Monatssummen für die Übersicht + /// + /// + private async Task LoadData() + { + try + { - /// - /// Lädt die Arbeitszeiten für einen Tag - /// - /// - /// - public async Task LoadDay(DateTime date) { - DayTotal = new TimeOnly(0); + _hour = await Models.Stunde.LoadData(); + RefreshProperties(); + } + catch (Exception e) + { + AlertEvent?.Invoke(this, e.Message); + } + } - try { - DayTimes = await Models.Stunde.LoadDay(date); + /// + /// Lädt die Arbeitszeiten für einen Tag + /// + /// + /// + public async Task LoadDay(DateTime date) + { + DayTotal = new TimeOnly(0); - //TODO: Hier muss noch die Berechnung der Stunden erfolgen - //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 ...) + try + { + await LoadSettings(); + DayTimes = await Models.Stunde.LoadDay(date); - TimeSpan span = TimeSpan.Zero; - foreach (DayTime dt in DayTimes) { - span += dt.end - dt.begin; - } - DayTotal = TimeOnly.FromTimeSpan(span); + //TODO: Hier muss noch die Berechnung der Stunden erfolgen + //Es werden im Moment nur die eingetragenen Stunden gezählt + //Auf der Website bekommt der Benutzer hingegen die berechneten Stunden angezeigt (Nachstunden außerhalb des Stundenplanes zählen mehr ...) - } catch (Exception e) { - DayTimes = new ObservableCollection(); - //TODO: hier könnte auch ein Fehler kommen, dann wäre InfoEvent falsch. - InfoEvent?.Invoke(this, e.Message); - } finally { - OnPropertyChanged(nameof(DayTotal)); - //OnPropertyChanged(nameof(DayTimes)); - } + TimeSpan span = TimeSpan.Zero; + foreach (DayTime dt in DayTimes) + { + span += dt.end - dt.begin; + } + DayTotal = TimeOnly.FromTimeSpan(span); - } + } + catch (Exception e) + { + DayTimes = new ObservableCollection(); + //TODO: hier könnte auch ein Fehler kommen, dann wäre InfoEvent falsch. + InfoEvent?.Invoke(this, e.Message); + } + finally + { + OnPropertyChanged(nameof(DayTotal)); + //OnPropertyChanged(nameof(DayTimes)); + } + + } + + private async Task LoadSettings() + { + Settings = await Models.Stunde.LoadSettings(); + } - async void IQueryAttributable.ApplyQueryAttributes(IDictionary query) { - if (query.ContainsKey("date")) { - await LoadDay(Convert.ToDateTime(query["date"])); - } - } + async void IQueryAttributable.ApplyQueryAttributes(IDictionary query) + { + if (query.ContainsKey("date")) + { + await LoadDay(Convert.ToDateTime(query["date"])); + } + } - private async Task RefreshItemsAsync() { + private async Task RefreshItemsAsync() + { IsRefreshing = true; // Fügen Sie hier die Logik zum Aktualisieren der Daten hinzu @@ -249,26 +296,31 @@ internal class StundenViewModel : ObservableObject, IQueryAttributable, INotifyP /// /// Refreshes all properties /// - private void RefreshProperties() { - OnPropertyChanged(nameof(Nominal)); - OnPropertyChanged(nameof(Overtime)); - OnPropertyChanged(nameof(OvertimeMonth)); - OnPropertyChanged(nameof(ZeitCalculated)); - OnPropertyChanged(nameof(Holiday)); - OnPropertyChanged(nameof(Hours)); - OnPropertyChanged(nameof(Title)); - OnPropertyChanged(nameof(MinimumDate)); - OnPropertyChanged(nameof(MaximumDate)); - } + private void RefreshProperties() + { + OnPropertyChanged(nameof(Nominal)); + OnPropertyChanged(nameof(Overtime)); + OnPropertyChanged(nameof(OvertimeMonth)); + OnPropertyChanged(nameof(ZeitCalculated)); + OnPropertyChanged(nameof(Holiday)); + OnPropertyChanged(nameof(Hours)); + OnPropertyChanged(nameof(Title)); + OnPropertyChanged(nameof(MinimumDate)); + OnPropertyChanged(nameof(MaximumDate)); + } - protected void OnPropertyChanged([CallerMemberName] string propertyName = null) { - try { - base.OnPropertyChanged(new PropertyChangedEventArgs(propertyName)); - } catch (Exception ex) { - AlertEvent?.Invoke(this, ex.Message); - //Console.WriteLine($"Fehler bei OnPropertyChanged: {ex.Message}"); - } - } + protected void OnPropertyChanged([CallerMemberName] string propertyName = null) + { + try + { + base.OnPropertyChanged(new PropertyChangedEventArgs(propertyName)); + } + catch (Exception ex) + { + AlertEvent?.Invoke(this, ex.Message); + //Console.WriteLine($"Fehler bei OnPropertyChanged: {ex.Message}"); + } + } } diff --git a/Jugenddienst Stunden/Views/StundePage.xaml b/Jugenddienst Stunden/Views/StundePage.xaml index 28b9563..170cb3c 100644 --- a/Jugenddienst Stunden/Views/StundePage.xaml +++ b/Jugenddienst Stunden/Views/StundePage.xaml @@ -38,9 +38,9 @@ - + - + diff --git a/Jugenddienst Stunden/Views/StundenPage.xaml b/Jugenddienst Stunden/Views/StundenPage.xaml index cddcb68..72a8057 100644 --- a/Jugenddienst Stunden/Views/StundenPage.xaml +++ b/Jugenddienst Stunden/Views/StundenPage.xaml @@ -77,8 +77,8 @@