using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using Jugenddienst_Stunden.Models;
using Jugenddienst_Stunden.Types;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows.Input;
using CommunityToolkit.Maui.Alerts;
using CommunityToolkit.Maui.Core;
namespace Jugenddienst_Stunden.ViewModels;
///
/// ViewModel für die Stundenliste
///
internal partial class StundenViewModel : ObservableObject, IQueryAttributable, INotifyPropertyChanged {
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;
///
/// Beschriftung Button Monatsübersicht
///
[ObservableProperty]
private string loadOverview;
//private HoursBase HoursBase = new HoursBase();
internal Settings Settings = new Settings();
///
/// Zu leistende Stunden
///
[ObservableProperty]
private TimeOnly sollstunden;
///
/// Geleistete Stunden an einem Tag
///
[ObservableProperty]
private TimeOnly dayTotal;
///
/// Liste der Tageszeiten
///
[ObservableProperty]
private List dayTimes = new List();
public string Title { get; set; } = GlobalVar.Name + " " + GlobalVar.Surname;
private Hours _hour;
public Hours Hours {
get => _hour;
}
///
/// 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;
LoadOverview = "Lade Summen für " + dateToday.ToString("MMMM");
//OnPropertyChanged();
Task.Run(() => LoadDay(value));
}
}
}
///
/// Monatsübersicht: Geleistete Stunden
///
public string? ZeitCalculated {
get => Hours.Zeit_total;
}
///
/// Monatsübersicht: Sollstunden
///
public int? Nominal {
get => Hours.Nominal;
}
///
/// Monatsübersicht: Differenz zwischen Soll und geleisteten Stunden
///
public int? Overtime {
get => Hours.overtime;
}
///
/// Monatsübersicht: Restüberstunden insgesamt
///
public int OvertimeMonth {
get => Hours.overtime_month;
}
///
/// Monatsübersicht: Resturlaub
///
public int Holiday {
get => Hours.holiday;
}
///
/// Seite neu laden
///
[ObservableProperty]
private bool isRefreshing;
///
/// Dürfen Gemeinden verwendet werden?
///
public bool GemeindeAktivSet { get; set; }
///
/// Dürfen Projekte verwendet werden?
///
public bool ProjektAktivSet { get; set; }
private bool doContinue = true;
///
/// CTOR
///
public StundenViewModel() {
_hour = new Hours();
LoadOverview = "Lade Summen für " + DateToday.ToString("MMMM");
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 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 {
BaseResponse dat = await HoursBase.LoadBase("hours&month=" + DateToday.ToString("MM"));
_hour = dat.hour;
//_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);
Sollstunden = new TimeOnly(0);
try {
//_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 _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);
//Nach der Tagessumme die anderen Tage anhängen
if (DayTimes != null) {
BaseResponse dat1 = await HoursBase.LoadBase("date=" + date.ToString("yyyy-MM-dd") + "&tilldate=" + date.AddDays(3).ToString("yyyy-MM-dd"));
if (dat1.daytimes != null)
DayTimes = dat.daytimes.Concat(dat1.daytimes).ToList();
}
} 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(DateToday));
OnPropertyChanged(nameof(LoadOverview));
//OnPropertyChanged(nameof(DayTimes));
}
}
async void IQueryAttributable.ApplyQueryAttributes(IDictionary query) {
if (query.ContainsKey("date")) {
await LoadDay(Convert.ToDateTime(query["date"]));
}
}
///
/// Seite aktualisieren
///
private async Task RefreshItemsAsync() {
IsRefreshing = true;
//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));
OnPropertyChanged(nameof(LoadOverview));
}
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}");
}
}
}