using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; using Jugenddienst_Stunden.Models; using Jugenddienst_Stunden.Types; using System.ComponentModel; using System.Windows.Input; using static System.Runtime.InteropServices.JavaScript.JSType; using Jugenddienst_Stunden.Interfaces; using Jugenddienst_Stunden.Repositories; using Jugenddienst_Stunden.Services; using Jugenddienst_Stunden.Infrastructure; using Jugenddienst_Stunden.Validators; using System.Net.Http; namespace Jugenddienst_Stunden.ViewModels; /// /// Viewmodel für die einzelnen Stundeneinträge / Bearbeitung /// public partial class StundeViewModel : ObservableObject, IQueryAttributable { private readonly IHoursService _hoursService; private readonly IAppSettings _settings; private readonly IAlertService _alertService; public int Id { get; set; } public string Title { get; set; } = "Eintrag bearbeiten"; public string SubTitle { get; set; } = DateTime.Today.ToString("dddd, d. MMMM yyyy"); public event EventHandler AlertEvent; public event EventHandler InfoEvent; public event Func> ConfirmEvent; //public event Func> ConfirmEvent; //public event EventHandler ConfirmEvent; /// /// Gemeinden für die Auswahlliste /// [ObservableProperty] private List optionsGemeinde; /// /// Projekte für die Auswahlliste /// [ObservableProperty] private List optionsProjekt; /// /// Freistellungen für die Auswahlliste /// [ObservableProperty] private List optionsFreistellung; /// /// Vorhandene Zeiten anzeigen, wenn neuer Eintrag erstellt wird /// [ObservableProperty] private List dayTimes; /// /// Aktueller Stundeneintrag /// [ObservableProperty] private DayTime dayTime; /// /// Dürfen Gemeinden verwendet werden? /// [ObservableProperty] private bool gemeindeAktivSet; /// /// Dürfen Projekte verwendet werden? /// [ObservableProperty] private bool projektAktivSet; [ObservableProperty] private bool freistellungEnabled; public ICommand SaveCommand { get; private set; } public ICommand DeleteCommand { get; private set; } public ICommand DeleteConfirmCommand { get; private set; } public ICommand SelectEntryCommand { get; } //public ICommand LoadDataCommand { get; private set; } public StundeViewModel(IHoursService hoursService, IAlertService alertService, IAppSettings settings) { _hoursService = hoursService; _settings = settings; _alertService = alertService; SaveCommand = new AsyncRelayCommand(Save); DeleteConfirmCommand = new Command(async () => await DeleteConfirm()); SelectEntryCommand = new AsyncRelayCommand(SelectEntryAsync); _alertService.AlertRaised += (s, msg) => AlertEvent?.Invoke(this, msg); } private void UpdateSettings(Settings settings) { _settings.Settings = settings; OptionsGemeinde = settings.Gemeinden; OptionsProjekt = settings.Projekte; OptionsFreistellung = settings.Freistellungen; GemeindeAktivSet = settings.GemeindeAktivSet; ProjektAktivSet = settings.ProjektAktivSet; } async Task Save() { bool exceptionOccurred = false; bool proceed = true; //Arbeitszeit sollte nicht null sein if (DayTime.TimeSpanVon == DayTime.TimeSpanBis && DayTime.FreistellungAktiv.Name == null) { proceed = false; AlertEvent?.Invoke(this, "Uhrzeiten sollten unterschiedlich sein"); } //Projekt ist ein Pflichtfeld if (_settings.Settings.ProjektAktivSet) { var projektId = DayTime.ProjektAktiv?.Id ?? 0; if (projektId == 0) { proceed = false; AlertEvent?.Invoke(this, "Projekt darf nicht leer sein"); } } //Gemeinde ist ein Pflichtfeld if (_settings.Settings.GemeindeAktivSet) { var gemeindeId = DayTime.GemeindeAktiv?.Id ?? 0; if (gemeindeId == 0) { proceed = false; AlertEvent?.Invoke(this, "Gemeinde darf nicht leer sein"); } } if (proceed) { try { await _hoursService.SaveEntryAsync(DayTime); } catch (Exception e) { AlertEvent?.Invoke(this, e.Message); exceptionOccurred = true; } if (!exceptionOccurred) { if (DayTime.Id != null) { //await Shell.Current.GoToAsync($"..?saved={DayTime.Id}"); await Shell.Current.GoToAsync($"//StundenPage?saved={DayTime.Id}"); } else { await Shell.Current.GoToAsync($"..?date={DayTime.Day.ToString("yyyy-MM-dd")}"); } } } } /// /// Löschen ohne Bestätigung /// private async Task Delete() { await _hoursService.DeleteEntryAsync(DayTime); await Shell.Current.GoToAsync($"..?date={DayTime.Day.ToString("yyyy-MM-dd")}"); } /// /// Löschen mit Bestätigung /// 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 try { await _hoursService.DeleteEntryAsync(DayTime); await Shell.Current.GoToAsync($"..?date={DayTime.Day.ToString("yyyy-MM-dd")}"); } catch (Exception e) { AlertEvent?.Invoke(this, e.Message); } } else { //nicht Löschen } } } /// /// Ö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"); } /// /// Anwenden der Query-Parameter /// async void IQueryAttributable.ApplyQueryAttributes(IDictionary query) { //load beinhaltet die ID: Eintrag bearbeiten //date beinhaltet einen Tag: Neuen Eintrag erstellen if (query.ContainsKey("load")) { //DateTime heute = DateTime.Now; try { //var entry = await _hoursService.GetEntryAsync(Convert.ToInt32(query["load"])); var (entry, settings, daytimes) = await _hoursService.GetEntryWithSettingsAsync(Convert.ToInt32(query["load"])); UpdateSettings(settings); DayTime = entry; DayTime.TimeSpanVon = entry.Begin.ToTimeSpan(); DayTime.TimeSpanBis = entry.End.ToTimeSpan(); DayTime.GemeindeAktiv = OptionsGemeinde.FirstOrDefault(Gemeinde => Gemeinde.Id == DayTime.Gemeinde) ?? new Gemeinde(); DayTime.ProjektAktiv = OptionsProjekt.FirstOrDefault(Projekt => Projekt.Id == DayTime.Projekt) ?? new Projekt(); DayTime.FreistellungAktiv = OptionsFreistellung.FirstOrDefault(Freistellung => Freistellung.Id == DayTime.Free) ?? new Freistellung(); OnPropertyChanged(nameof(DayTime)); if (System.String.IsNullOrEmpty(DayTime.Description)) { InfoEvent?.Invoke(this, "Eintrag hat keinen Beschreibungstext"); } SubTitle = DayTime.Day.ToString("dddd, d. MMMM yyyy"); OnPropertyChanged(nameof(SubTitle)); FreistellungEnabled = !DayTime.Approved; DayTimes = daytimes; OnPropertyChanged(nameof(DayTimes)); } catch (Exception e) { AlertEvent?.Invoke(this, e.Message); } //OnPropertyChanged(nameof(DayTime)); } else if (query.ContainsKey("date")) { Title = "Neuer Eintrag"; OnPropertyChanged(nameof(Title)); DateTime _date = DateTime.ParseExact((string)query["date"], "yyyy-MM-dd", System.Globalization.CultureInfo.InvariantCulture); //Bei neuem Eintrag die vorhandenen des gleichen Tages anzeigen try { var (list, settings) = await _hoursService.GetDayWithSettingsAsync(_date); UpdateSettings(settings); DayTimes = list; OnPropertyChanged(nameof(DayTimes)); } catch (Exception) { //Ein Tag ohne Einträge gibt eine Fehlermeldung, //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(); var settings = await _hoursService.GetSettingsAsync(); UpdateSettings(settings); } finally { DayTime = new DayTime(); DayTime.Day = _date; DayTime.EmployeeId = _settings.EmployeeId; DayTime.GemeindeAktiv = new Gemeinde(); DayTime.ProjektAktiv = new Projekt(); DayTime.FreistellungAktiv = new Freistellung(); SubTitle = _date.ToString("dddd, d. MMMM yyyy"); FreistellungEnabled = true; OnPropertyChanged(nameof(SubTitle)); //OnPropertyChanged(nameof(DayTime)); } } } }