using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; using Jugenddienst_Stunden.Types; using System.Collections.ObjectModel; using System.ComponentModel; using System.Runtime.CompilerServices; 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") + ": "; public ICommand NewEntryCommand { get; } public ICommand SelectEntryCommand { get; } public ICommand LoadDataCommand { get; private set; } public event EventHandler AlertEvent; public event EventHandler InfoEvent; private string _title = Preferences.Default.Get("name", "") + " " + Preferences.Default.Get("surname", ""); public string Title { get => _title; set => SetProperty(ref _title, value); } private Hours _hour; public Hours Hours { get => _hour; } /// /// 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); } /// /// Mindest-Datum für den Datepicker /// public static DateTime MinimumDate { get => DateTime.Today.AddDays(-365); } /// /// Höchst-Datum für den Datepicker /// public static 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(); _ = LoadDay(value); } } } /// /// Monatsübersicht: Geleistete Stunden /// public string? ZeitCalculated { get => _hour.zeit_total; } /// /// 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: Restüberstunden insgesamt /// public string OvertimeMonth { get => _hour.overtime_month; } /// /// 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); 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 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)}?load={entry.id}"); await Shell.Current.GoToAsync($"{nameof(Views.StundePage)}", navigationParameters); } else AlertEvent?.Invoke(this, "Auswahl enthält keine Daten"); } /// /// 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 Arbeitszeiten für einen Tag /// /// /// public async Task LoadDay(DateTime date) { DayTotal = new TimeOnly(0); try { DayTimes = await Models.Stunde.LoadDay(date); //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 ...) 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)); } } async void IQueryAttributable.ApplyQueryAttributes(IDictionary query) { if (query.ContainsKey("date")) { await LoadDay(Convert.ToDateTime(query["date"])); } } /// /// 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)); } 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}"); } } }