Beachte die Einstellung ob Projekte und Gemeinden aktiv sind. Verbiete Änderungen an der Freistellung, wenn sie genehmigt wurde. Vereinfache das Speichern der Einstellungen Bessere Fehlerbehandlung, einheitlichere API
317 lines
9.3 KiB
C#
317 lines
9.3 KiB
C#
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;
|
|
|
|
|
|
namespace Jugenddienst_Stunden.ViewModels;
|
|
/// <summary>
|
|
/// ViewModel für die Stundenliste
|
|
/// </summary>
|
|
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<string> AlertEvent;
|
|
public event EventHandler<string> InfoEvent;
|
|
|
|
//private HoursBase HoursBase = new HoursBase();
|
|
internal Settings Settings = new Settings();
|
|
|
|
public TimeOnly Sollstunden { get; set; }
|
|
|
|
|
|
public string Title { get; set; } = GlobalVar.Name + " " + GlobalVar.Surname;
|
|
|
|
private Hours _hour;
|
|
public Hours Hours {
|
|
get => _hour;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gesamtstunden an einem Tag
|
|
/// </summary>
|
|
public TimeOnly DayTotal { get; set; }
|
|
|
|
/// <summary>
|
|
/// Liste der Tageszeiten
|
|
/// </summary>
|
|
private List<DayTime> _dayTimes = new List<DayTime>();
|
|
public List<DayTime> DayTimes {
|
|
get => _dayTimes;
|
|
set {
|
|
SetProperty(ref _dayTimes, value);
|
|
OnPropertyChanged(nameof(DayTimes));
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Mindest-Datum für den Datepicker
|
|
/// </summary>
|
|
public DateTime MinimumDate {
|
|
get => DateTime.Today.AddDays(-365);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Höchst-Datum für den Datepicker
|
|
/// </summary>
|
|
public DateTime MaximumDate {
|
|
get => DateTime.Today.AddDays(60);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Heutiges Datum, wenn das Datum geändert wird, wird auch der Tag geladen
|
|
/// </summary>
|
|
private DateTime dateToday = DateTime.Today;
|
|
public DateTime DateToday {
|
|
get => dateToday;
|
|
set {
|
|
if (dateToday != value) {
|
|
dateToday = value;
|
|
//GetDay = value;
|
|
//OnPropertyChanged();
|
|
Task.Run(() => LoadDay(value));
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Monatsübersicht: Geleistete Stunden
|
|
/// </summary>
|
|
public string? ZeitCalculated {
|
|
get => Hours.Zeit_total;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Monatsübersicht: Sollstunden
|
|
/// </summary>
|
|
public string? Nominal {
|
|
get => Hours.Nominal;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Monatsübersicht: Differenz zwischen Soll und geleisteten Stunden
|
|
/// </summary>
|
|
public string? Overtime {
|
|
get => Hours.overtime;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Monatsübersicht: Restüberstunden insgesamt
|
|
/// </summary>
|
|
public string OvertimeMonth {
|
|
get => Hours.overtime_month;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Monatsübersicht: Resturlaub
|
|
/// </summary>
|
|
public string Holiday {
|
|
get => Hours.holiday;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Seite neu laden
|
|
/// </summary>
|
|
private bool isRefreshing;
|
|
public bool IsRefreshing {
|
|
get => isRefreshing;
|
|
set {
|
|
if (isRefreshing != value) {
|
|
isRefreshing = value;
|
|
OnPropertyChanged();
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Dürfen Gemeinden verwendet werden?
|
|
/// </summary>
|
|
public bool GemeindeAktivSet { get; set; }
|
|
|
|
/// <summary>
|
|
/// Dürfen Projekte verwendet werden?
|
|
/// </summary>
|
|
public bool ProjektAktivSet { get; set; }
|
|
|
|
private bool doContinue = true;
|
|
|
|
|
|
/// <summary>
|
|
/// CTOR
|
|
/// </summary>
|
|
public StundenViewModel() {
|
|
_hour = new Hours();
|
|
|
|
//LoadSettingsAsync();
|
|
//HoursBase.tokendata = new TokenData(HoursBase.apiKey);
|
|
LoadDataCommand = new AsyncRelayCommand(LoadData);
|
|
NewEntryCommand = new AsyncRelayCommand(NewEntryAsync);
|
|
SelectEntryCommand = new AsyncRelayCommand<DayTime>(SelectEntryAsync);
|
|
RefreshListCommand = new AsyncRelayCommand(RefreshList);
|
|
RefreshCommand = new Command(async () => await RefreshItemsAsync());
|
|
|
|
Task task = LoadDay(DateTime.Today);
|
|
|
|
}
|
|
|
|
|
|
private async Task LoadSettingsAsync() {
|
|
try {
|
|
Settings = await HoursBase.LoadSettings();
|
|
|
|
GemeindeAktivSet = Settings.GemeindeAktivSet;
|
|
ProjektAktivSet = Settings.ProjektAktivSet;
|
|
|
|
OnPropertyChanged(nameof(GemeindeAktivSet));
|
|
OnPropertyChanged(nameof(ProjektAktivSet));
|
|
doContinue = true;
|
|
} catch (Exception e) {
|
|
doContinue = false;
|
|
AlertEvent?.Invoke(this, e.Message);
|
|
}
|
|
|
|
}
|
|
|
|
/// <summary>
|
|
/// Öffnet eine neue Stundeneingabe
|
|
/// </summary>
|
|
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}");
|
|
}
|
|
|
|
/// <summary>
|
|
/// Öffnet eine bestehende Stundeneingabe
|
|
/// </summary>
|
|
private async Task SelectEntryAsync(DayTime entry) {
|
|
if (entry != null && entry.Id != null) {
|
|
//var navigationParameters = new Dictionary<string, object> { { "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));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Lädt die Monatssummen für die Übersicht
|
|
/// </summary>
|
|
private async Task LoadData() {
|
|
try {
|
|
_hour = await HoursBase.LoadData();
|
|
RefreshProperties();
|
|
} catch (Exception e) {
|
|
AlertEvent?.Invoke(this, e.Message);
|
|
}
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Lädt die Arbeitszeiten für einen Tag
|
|
/// </summary>
|
|
public async Task LoadDay(DateTime date) {
|
|
DayTotal = new TimeOnly(0);
|
|
//await LoadSettingsAsync();
|
|
//if (doContinue) {
|
|
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<Sollstunden> _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<DayTime>();
|
|
//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<string, object> 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;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Refreshes all properties
|
|
/// </summary>
|
|
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}");
|
|
}
|
|
}
|
|
|
|
|
|
}
|