using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; using Jugenddienst_Stunden.Models; using Jugenddienst_Stunden.Types; 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; /// /// Stundenliste /// internal class StundenViewModel : ObservableObject, IQueryAttributable, INotifyPropertyChanged { public string LoadOverview => "Lade Summen für " + DateTime.Today.ToString("MMMM"); 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; private HoursBase HoursBase = new HoursBase(); internal Settings Settings = new Settings(); public TimeOnly Sollstunden { get; set; } private string _title = HoursBase.name + " " + HoursBase.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 List _dayTimes = new List(); public List DayTimes { get => _dayTimes; set { SetProperty(ref _dayTimes, value); OnPropertyChanged(nameof(DayTimes)); } } /// /// 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); } /// /// 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 => Hours.Zeit_total; } /// /// Monatsübersicht: Sollstunden /// public string? Nominal { get => Hours.Nominal; } /// /// Monatsübersicht: Differenz zwischen Soll und geleisteten Stunden /// public string? Overtime { get => Hours.overtime; } /// /// Monatsübersicht: Restüberstunden insgesamt /// public string OvertimeMonth { get => Hours.overtime_month; } /// /// Monatsübersicht: Resturlaub /// public string Holiday { get => Hours.holiday; } /// /// Seite neu laden /// private bool isRefreshing; public bool IsRefreshing { get => isRefreshing; set { if (isRefreshing != value) { isRefreshing = value; OnPropertyChanged(); } } } /// /// Dürfen Gemeinden verwendet werden? /// public bool GemeindeAktivSet { get; set; } /// /// Dürfen Projekte verwendet werden? /// public bool ProjektAktivSet { get; set; } /// /// CTOR /// public StundenViewModel() { _hour = new 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); LoadSettingsAsync(); } private async void LoadSettingsAsync() { Settings = await HoursBase.LoadSettings(); GemeindeAktivSet = Settings.GemeindeAktivSet; ProjektAktivSet = Settings.ProjektAktivSet; OnPropertyChanged(nameof(GemeindeAktivSet)); OnPropertyChanged(nameof(ProjektAktivSet)); } /// /// Öffnet eine neue Stundeneingabe /// private async Task NewEntryAsync() { //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"); } private async Task RefreshList() { OnPropertyChanged(nameof(DayTimes)); } /// /// Lädt die Monatssummen für die Übersicht /// private async Task LoadData() { try { _hour = await HoursBase.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); LoadSettingsAsync(); try { DayTimes = await HoursBase.LoadDay(date); List _soll; TimeSpan span = TimeSpan.Zero; bool merker = false; foreach (DayTime dt in DayTimes) { span += dt.End - dt.Begin; //Nachtstunden dazurechnen if (dt.Night.Ticks > 0 && !merker) { span += dt.Night.ToTimeSpan() * .5; merker = true; } _soll = Settings.Nominal.Where(w => w.Timetable == dt.TimeTable && w.Wochentag == dt.Wday).ToList(); if (_soll.Count > 0) Sollstunden = TimeOnly.FromTimeSpan(TimeSpan.FromHours(_soll[0].Zeit)); } DayTotal = TimeOnly.FromTimeSpan(span); } catch (Exception e) { DayTimes = new List(); //TODO: hier könnte auch ein Fehler kommen, dann wäre InfoEvent falsch. InfoEvent?.Invoke(this, e.Message); } finally { OnPropertyChanged(nameof(DayTotal)); OnPropertyChanged(nameof(Sollstunden)); //OnPropertyChanged(nameof(DayTimes)); } } async void IQueryAttributable.ApplyQueryAttributes(IDictionary query) { if (query.ContainsKey("date")) { await LoadDay(Convert.ToDateTime(query["date"])); } } private async Task RefreshItemsAsync() { IsRefreshing = true; // Fügen Sie hier die Logik zum Aktualisieren der Daten hinzu //await Task.Delay(2000); // Simuliert eine Datenaktualisierung await LoadDay(DateToday); IsRefreshing = false; } /// /// 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}"); } } }