Utopia-Canteen-System/ViewModels/MealSchedulesViewModel.cs

374 lines
13 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

//using System.Collections.ObjectModel;
//using System.Windows;
//using CommunityToolkit.Mvvm.ComponentModel;
//using CommunityToolkit.Mvvm.Input;
//using MySqlConnector;
//using UtopiaCanteenSystem.Models;
//using UtopiaCanteenSystem.Services;
//namespace UtopiaCanteenSystem.ViewModels;
///// <summary>
///// Admin CRUD for meal schedules in production (hrms.meal_schedule). No SQLite. Load all on open; optional Site filter (local).
///// </summary>
//public partial class MealSchedulesViewModel : ObservableObject
//{
// private readonly IMealScheduleService _mealScheduleService;
// private readonly INavigationService _navigation;
// [ObservableProperty]
// private ObservableCollection<MealSchedule> _schedules = new();
// /// <summary>Full list from production; Schedules is filtered by SelectedSiteFilter.</summary>
// private List<MealSchedule> _allSchedules = new();
// [ObservableProperty]
// private ObservableCollection<string> _siteFilterChoices = new() { "All" };
// [ObservableProperty]
// private string _selectedSiteFilter = "All";
// [ObservableProperty]
// private MealSchedule? _selectedSchedule;
// [ObservableProperty]
// private string _locationSiteId = string.Empty;
// [ObservableProperty]
// private string _mealName = string.Empty;
// [ObservableProperty]
// private string _startTime = "06:00:00";
// [ObservableProperty]
// private string _endTime = "09:00:00";
// [ObservableProperty]
// private string _message = string.Empty;
// [ObservableProperty]
// private bool _isError;
// [ObservableProperty]
// private bool _isLoading;
// public MealSchedulesViewModel(IMealScheduleService mealScheduleService, INavigationService navigation)
// {
// _mealScheduleService = mealScheduleService;
// _navigation = navigation;
// _ = LoadSchedulesAsync();
// }
// partial void OnSelectedSiteFilterChanged(string value)
// {
// ApplyFilter();
// }
// partial void OnSelectedScheduleChanged(MealSchedule? value)
// {
// if (value == null) return;
// LocationSiteId = value.LocationSiteId ?? string.Empty;
// MealName = value.MealName ?? string.Empty;
// StartTime = value.StartTime ?? "00:00:00";
// EndTime = value.EndTime ?? "23:59:59";
// }
// private void ApplyFilter()
// {
// if (string.IsNullOrEmpty(SelectedSiteFilter) || SelectedSiteFilter == "All")
// {
// Schedules = new ObservableCollection<MealSchedule>(_allSchedules);
// return;
// }
// var filtered = _allSchedules.Where(s => string.Equals(s.LocationSiteId?.Trim(), SelectedSiteFilter.Trim(), StringComparison.OrdinalIgnoreCase)).ToList();
// Schedules = new ObservableCollection<MealSchedule>(filtered);
// }
// private async Task LoadSchedulesAsync()
// {
// IsLoading = true;
// Message = string.Empty;
// IsError = false;
// try
// {
// var list = await _mealScheduleService.GetAllSchedulesAsync().ConfigureAwait(true);
// _allSchedules = list.ToList();
// var siteIds = _allSchedules.Select(s => s.LocationSiteId?.Trim() ?? "").Where(s => !string.IsNullOrEmpty(s)).Distinct().OrderBy(s => s, StringComparer.Ordinal).ToList();
// SiteFilterChoices = new ObservableCollection<string>(new[] { "All" }.Concat(siteIds));
// SelectedSiteFilter = "All";
// ApplyFilter();
// if (_allSchedules.Count == 0)
// Message = "No schedules in production. Add one below (HRMS MySQL must be configured).";
// }
// catch (Exception ex)
// {
// IsError = true;
// var msg = ex is MySqlException mysql
// ? $"{mysql.Message}{Environment.NewLine}{Environment.NewLine}{mysql.StackTrace}"
// : $"{ex.Message}{Environment.NewLine}{Environment.NewLine}{ex.StackTrace}";
// Message = "Could not load schedules from production.";
// MessageBox.Show(msg, "Meal Schedules Load Error", MessageBoxButton.OK, MessageBoxImage.Error);
// }
// finally
// {
// IsLoading = false;
// }
// }
// [RelayCommand]
// private void AddNew()
// {
// SelectedSchedule = null;
// LocationSiteId = "02";
// MealName = string.Empty;
// StartTime = "06:00:00";
// EndTime = "09:00:00";
// Message = string.Empty;
// }
// [RelayCommand]
// private async Task Save()
// {
// Message = string.Empty;
// IsError = false;
// if (!TimeSpan.TryParse(StartTime?.Trim(), out var start) || !TimeSpan.TryParse(EndTime?.Trim(), out var end))
// {
// Message = "Start time and end time must be in HH:mm:ss format.";
// IsError = true;
// return;
// }
// if (start >= end)
// {
// Message = "Start time must be before end time.";
// IsError = true;
// return;
// }
// var siteId = (LocationSiteId ?? string.Empty).Trim();
// if (string.IsNullOrEmpty(siteId))
// {
// Message = "Location site ID is required.";
// IsError = true;
// return;
// }
// try
// {
// if (SelectedSchedule != null)
// {
// var dto = new MealSchedule
// {
// Id = SelectedSchedule.Id,
// MealName = (MealName ?? string.Empty).Trim(),
// LocationSiteId = siteId,
// StartTime = StartTime.Trim(),
// EndTime = EndTime.Trim()
// };
// await _mealScheduleService.UpdateAsync(dto).ConfigureAwait(true);
// Message = "Schedule updated in production.";
// }
// else
// {
// var dto = new MealSchedule
// {
// MealName = (MealName ?? string.Empty).Trim(),
// LocationSiteId = siteId,
// StartTime = StartTime.Trim(),
// EndTime = EndTime.Trim()
// };
// await _mealScheduleService.CreateAsync(dto).ConfigureAwait(true);
// Message = "Schedule added to production.";
// }
// await LoadSchedulesAsync().ConfigureAwait(true);
// }
// catch (Exception ex)
// {
// IsError = true;
// var msg = ex is MySqlException mysql
// ? $"{mysql.Message}{Environment.NewLine}{Environment.NewLine}{mysql.StackTrace}"
// : $"{ex.Message}{Environment.NewLine}{Environment.NewLine}{ex.StackTrace}";
// Message = "Failed to save to production.";
// MessageBox.Show(msg, "Meal Schedules Save Error", MessageBoxButton.OK, MessageBoxImage.Error);
// }
// }
// /// <summary>Selects a schedule for editing (used by Actions column Edit button).</summary>
// [RelayCommand]
// private void SelectSchedule(MealSchedule? schedule)
// {
// SelectedSchedule = schedule;
// }
// [RelayCommand]
// private async Task Delete(MealSchedule? row)
// {
// var toDelete = row ?? SelectedSchedule;
// if (toDelete == null)
// {
// Message = "Select a schedule to delete.";
// IsError = true;
// return;
// }
// Message = string.Empty;
// IsError = false;
// try
// {
// await _mealScheduleService.DeleteAsync(toDelete.Id).ConfigureAwait(true);
// Message = "Schedule deleted from production.";
// SelectedSchedule = null;
// await LoadSchedulesAsync().ConfigureAwait(true);
// }
// catch (Exception ex)
// {
// IsError = true;
// var msg = ex is MySqlException mysql
// ? $"{mysql.Message}{Environment.NewLine}{Environment.NewLine}{mysql.StackTrace}"
// : $"{ex.Message}{Environment.NewLine}{Environment.NewLine}{ex.StackTrace}";
// Message = "Failed to delete.";
// MessageBox.Show(msg, "Meal Schedules Delete Error", MessageBoxButton.OK, MessageBoxImage.Error);
// }
// }
// [RelayCommand]
// private void Back()
// {
// _navigation.NavigateToSettings();
// }
//}
using System.Collections.ObjectModel;
using System.Windows;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using MySqlConnector;
using UtopiaCanteenSystem.Models;
using UtopiaCanteenSystem.Services;
namespace UtopiaCanteenSystem.ViewModels;
/// <summary>
/// View-only display of meal schedules from production.
/// Loads all schedules on open; optional Site filter.
/// </summary>
public partial class MealSchedulesViewModel : ObservableObject
{
private readonly IMealScheduleService _mealScheduleService;
private readonly INavigationService _navigation;
private readonly IConfigService _configService;
private readonly string _currentSiteId;
[ObservableProperty]
private ObservableCollection<MealSchedule> _schedules = new();
private List<MealSchedule> _allSchedules = new();
[ObservableProperty]
private ObservableCollection<string> _siteFilterChoices = new() { "All" };
[ObservableProperty]
private string _selectedSiteFilter = "All";
[ObservableProperty]
private MealSchedule? _selectedSchedule;
[ObservableProperty]
private string _message = string.Empty;
[ObservableProperty]
private bool _isError;
[ObservableProperty]
private bool _isLoading;
public MealSchedulesViewModel(IMealScheduleService mealScheduleService, INavigationService navigation, IConfigService configService)
{
_mealScheduleService = mealScheduleService;
_navigation = navigation;
_configService = configService;
_currentSiteId = (_configService.GetSiteId() ?? string.Empty).Trim();
_ = LoadSchedulesAsync();
}
partial void OnSelectedSiteFilterChanged(string value)
{
ApplyFilter();
}
private void ApplyFilter()
{
// Remove "SITE : " from the config SiteId and normalize it (pad with leading zeros if necessary)
var site = string.IsNullOrWhiteSpace(_currentSiteId)
? "01"
: _currentSiteId.Replace("SITE : ", "").PadLeft(2, '0'); // Normalize to two digits if empty or contains "SITE : "
// Log the site ID we're filtering by (for debugging purposes).
Console.WriteLine($"Filtering for site: {site}");
// Filter the meal schedules by the normalized site ID.
var filtered = _allSchedules
.Where(s =>
{
// Normalize the LocationSiteId from the schedule to ensure consistency.
var normalizedLocationSiteId = s.LocationSiteId?.Trim().PadLeft(2, '0') ?? "00";
Console.WriteLine($"Checking: {normalizedLocationSiteId} vs {site}");
return string.Equals(normalizedLocationSiteId, site, StringComparison.OrdinalIgnoreCase);
})
.ToList();
// Update the UI with the filtered results.
Schedules = new ObservableCollection<MealSchedule>(filtered);
}
private async Task LoadSchedulesAsync()
{
IsLoading = true;
Message = string.Empty;
IsError = false;
try
{
var list = await _mealScheduleService.GetAllSchedulesAsync().ConfigureAwait(true);
_allSchedules = list.ToList();
var siteIds = _allSchedules
.Select(s => s.LocationSiteId?.Trim() ?? "")
.Where(s => !string.IsNullOrEmpty(s))
.Distinct()
.OrderBy(s => s, StringComparer.Ordinal)
.ToList();
// Only show schedules for current configured site; hide other sites from filter choices.
SiteFilterChoices = new ObservableCollection<string>(new[] { string.IsNullOrWhiteSpace(_currentSiteId) ? "01" : _currentSiteId });
SelectedSiteFilter = SiteFilterChoices.First();
ApplyFilter();
if (_allSchedules.Count == 0)
Message = "No schedules configured.";
}
catch (Exception ex)
{
IsError = true;
var msg = ex is MySqlException mysql
? $"{mysql.Message}{Environment.NewLine}{Environment.NewLine}{mysql.StackTrace}"
: $"{ex.Message}{Environment.NewLine}{Environment.NewLine}{ex.StackTrace}";
Message = "Could not load schedules from backend.";
MessageBox.Show(msg, "Meal Schedules Load Error", MessageBoxButton.OK, MessageBoxImage.Error);
}
finally
{
IsLoading = false;
}
}
[RelayCommand]
private void Back()
{
_navigation.NavigateToSettings();
}
}