using Comal.Classes; using InABox.Clients; using InABox.Core; using InABox.DynamicGrid; using InABox.WPF; using Microsoft.CodeAnalysis.VisualBasic.Syntax; using org.omg.PortableInterceptor; using PRSDesktop.Forms; using PRSDesktop.WidgetGroups; using System; using System.Collections.Generic; using System.ComponentModel; using System.Globalization; using System.Linq; using System.Runtime.CompilerServices; using System.Threading.Tasks; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Media; using System.Windows.Media.Imaging; using InABox.Configuration; using Client = InABox.Clients.Client; namespace PRSDesktop.Dashboards { public class EquipmentSchedulesDashboardProperties : IUserConfigurationSettings, IDashboardProperties { } public class ScheduleViewModel : INotifyPropertyChanged { private Guid employeeID; private string? employeeName; private string? employeeMobile; private string? employeeEmail; private BitmapImage? employeeImage; public bool HasEmployee => EmployeeID != Guid.Empty; public Guid ID { get; set; } public string Title { get; set; } public DateTime DueDate { get; set; } public BitmapImage? EmployeeImage { get => employeeImage; set { employeeImage = value; NotifyPropertyChanged(); } } public Guid EmployeeID { get => employeeID; set { employeeID = value; NotifyPropertyChanged(nameof(HasEmployee)); } } public string? EmployeeName { get => employeeName; set { employeeName = value; NotifyPropertyChanged(); } } public string? EmployeeMobile { get => employeeMobile; set { employeeMobile = value; NotifyPropertyChanged(); NotifyPropertyChanged(nameof(EmployeeContact)); } } public string? EmployeeEmail { get => employeeEmail; set { employeeEmail = value; NotifyPropertyChanged(); NotifyPropertyChanged(nameof(EmployeeContact)); } } public string? EmployeeContact { get { var str = ""; if (EmployeeEmail is not null) str = EmployeeEmail; if(EmployeeMobile is not null) { if (string.IsNullOrWhiteSpace(str)) { str = EmployeeMobile; } else { str += $", {EmployeeMobile}"; } } return string.IsNullOrWhiteSpace(str) ? null : str; } } public event PropertyChangedEventHandler? PropertyChanged; private void NotifyPropertyChanged([CallerMemberName] string propertyName = "") { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } } public class EquipmentScheduleViewModel { public bool HasLocation { get; set; } public Guid ID { get; set; } public string Code { get; set; } public string Description { get; set; } public List Schedules { get; set; } } [ValueConversion(typeof(DateTime), typeof(SolidColorBrush))] class ScheduleBackgroundConverter : IValueConverter { public Color GetColor(DateTime date) { var diff = date - DateTime.Today; if (diff < TimeSpan.Zero) return Colors.Salmon; else if (diff.TotalDays <= 7) return Colors.Orange; else if (diff.Days <= 30) return Colors.LightYellow; else return Colors.LightGreen; } public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { var date = (DateTime)value; var color = GetColor(date); return new SolidColorBrush(color); } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { throw new NotImplementedException(); } } /// /// Interaction logic for EquipmentSchedulesDashboard.xaml /// public partial class EquipmentSchedulesDashboard : UserControl, IDashboardWidget { public EquipmentSchedulesDashboardProperties Properties { get; set; } = null!; public event LoadSettings? LoadSettings; public event SaveSettings? SaveSettings; private Dictionary Equipment = new(); private Dictionary EmployeeImages = new(); private Dictionary Employees = new(); private List Models = new(); public EquipmentSchedulesDashboard() { InitializeComponent(); } public void Setup() { LoadEmployeeImages(); } private void LoadEmployeeImages() { Task.Run(() => { var employees = new Client() .Query( LookupFactory.DefineFilter(), new Columns( x => x.ID, x => x.Thumbnail.ID, x => x.Name, x => x.Mobile, x => x.Email)) .ToObjects().ToList(); var documents = new Client() .Query( new Filter(x => x.ID).InList(employees.Select(x => x.Thumbnail.ID).ToArray()), new Columns(x => x.ID).Add(x => x.Data)) .ToDictionary(x => x.ID, x => x.Data); return new { Employees = employees, Documents = documents }; }).ContinueWith((task) => { EmployeeImages = task.Result.Employees.ToDictionary( x => x.ID, x => { var document = task.Result.Documents.GetValueOrDefault(x.Thumbnail.ID); if (document is null) return null; return ImageUtils.BitmapImageFromBytes(document); }); Employees = task.Result.Employees.ToDictionary(x => x.ID, x => x); lock (Models) { var anonymous = PRSDesktop.Resources.anonymous.AsBitmapImage(); foreach (var model in Models) { foreach (var schedule in model.Schedules) { var employee = Employees?.GetValueOrDefault(schedule.EmployeeID); schedule.EmployeeImage = EmployeeImages?.GetValueOrDefault(schedule.EmployeeID) ?? anonymous; schedule.EmployeeMobile = employee?.Mobile; schedule.EmployeeName = employee?.Name; schedule.EmployeeEmail = employee?.Email; } } } }, TaskScheduler.FromCurrentSynchronizationContext()); } public void Refresh() { var results = Client.QueryMultiple( new KeyedQueryDef( new Filter().All(), new Columns(x => x.ID) .Add(x => x.Code) .Add(x => x.Description) .Add(x => x.TrackerLink.ID) .Add(x => x.TrackerLink.Location.Latitude) .Add(x => x.TrackerLink.Location.Longitude) .Add(x => x.TrackerLink.Location.Timestamp)), new KeyedQueryDef( new Filter(x => x.DocumentClass).IsEqualTo(typeof(Equipment).EntityName()), new Columns(x => x.ID) .Add(x => x.Title) .Add(x => x.DueDate) .Add(x => x.DocumentID) .Add(x => x.EmployeeLink.ID))); var equipmentItems = results.Get().Rows.Select(x => x.ToObject()); Equipment = equipmentItems.ToDictionary(x => x.ID, x => x); var schedules = results.Get().Rows .Select(x => x.ToObject()) .GroupBy(x => x.DocumentID) .ToDictionary(x => x.Key, x => x.OrderBy(x => x.DueDate).ToList()); var anonymous = PRSDesktop.Resources.anonymous.AsBitmapImage(); lock (Models) { Models = new List(); foreach (var equipmentItem in equipmentItems) { var equipmentSchedules = schedules.GetValueOrDefault(equipmentItem.ID); if (equipmentSchedules is not null) { var model = new EquipmentScheduleViewModel { Code = equipmentItem.Code, Description = equipmentItem.Description, ID = equipmentItem.ID, HasLocation = equipmentItem.TrackerLink.ID != Guid.Empty }; model.Schedules = equipmentSchedules .Select(x => { var employee = Employees.GetValueOrDefault(x.EmployeeLink.ID); return new ScheduleViewModel { Title = x.Title, DueDate = x.DueDate, ID = x.ID, EmployeeImage = EmployeeImages.GetValueOrDefault(x.EmployeeLink.ID) ?? anonymous, EmployeeID = x.EmployeeLink.ID, EmployeeEmail = employee?.Email, EmployeeMobile = employee?.Mobile, EmployeeName = employee?.Name }; }) .ToList() ?? new List(); Models.Add(model); } } } EquipmentList.ItemsSource = Models; } public void Shutdown() { } private void ViewEquipment_Click(object sender, System.Windows.RoutedEventArgs e) { var equipmentID = (Guid)(sender as MenuItem)!.Tag; var equipment = new Client().Load( new Filter(x => x.ID).IsEqualTo(equipmentID)).FirstOrDefault(); if(equipment != null) { var grid = DynamicGridUtils.CreateDynamicGrid(typeof(DynamicDataGrid<>), typeof(Equipment)); if(grid.EditItems(new[] { equipment })) { new Client().Save(equipment, "Edited by user from schedules dashboard"); Refresh(); } } } private void ViewSchedule_Click(object sender, System.Windows.RoutedEventArgs e) { var scheduleID = (Guid)(sender as MenuItem)!.Tag; var schedule = new Client().Load( new Filter(x => x.ID).IsEqualTo(scheduleID)).FirstOrDefault(); if (schedule != null) { var grid = DynamicGridUtils.CreateDynamicGrid(typeof(DynamicDataGrid<>), typeof(Schedule)); if (grid.EditItems(new[] { schedule })) { new Client().Save(schedule, "Edited by user from schedules dashboard"); Refresh(); } } } private void ViewEmployee_Click(object sender, System.Windows.RoutedEventArgs e) { var employeeID = (Guid)(sender as MenuItem)!.Tag; var employee = new Client().Load( new Filter(x => x.ID).IsEqualTo(employeeID)).FirstOrDefault(); if (employee != null) { var grid = DynamicGridUtils.CreateDynamicGrid(typeof(DynamicDataGrid<>), typeof(Employee)); if (grid.EditItems(new[] { employee })) { new Client().Save(employee, "Edited by user from schedules dashboard"); Refresh(); } } } private void EquipmentLocation_Click(object sender, System.Windows.RoutedEventArgs e) { var equipmentID = (Guid)(sender as Button)!.Tag; if (!Equipment.TryGetValue(equipmentID, out var equipment)) return; var form = new MapForm( equipment.TrackerLink.Location.Latitude, equipment.TrackerLink.Location.Longitude, equipment.TrackerLink.Location.Timestamp); form.ShowDialog(); } } public class EquipmentSchedulesDashboardElement : DashboardElement { } }