using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Windows; using System.Windows.Controls; using System.Windows.Media.Imaging; using Comal.Classes; using InABox.Clients; using InABox.Core; using InABox.DynamicGrid; using InABox.WPF; using Microsoft.Win32; using Syncfusion.Linq; using Button = System.Windows.Controls.Button; using MessageBox = System.Windows.MessageBox; using OpenFileDialog = Microsoft.Win32.OpenFileDialog; using SaveFileDialog = Microsoft.Win32.SaveFileDialog; namespace PRS.Shared { internal class ScheduleItemGrid : DynamicDataGrid { private readonly BitmapImage disabled = PRS.Shared.Resources.disabled.AsBitmapImage(); private readonly BitmapImage tick = PRS.Shared.Resources.tick.AsBitmapImage(); public ScheduleItemGrid() { Options.AddRange(DynamicGridOption.RecordCount, DynamicGridOption.SelectColumns, DynamicGridOption.MultiSelect); ActionColumns.Add(new DynamicTickColumn(x => x.Active, tick, tick, disabled, CheckClick)); HiddenColumns.Add(x => x.Active); HiddenColumns.Add(x => x.Title); HiddenColumns.Add(x => x.DocumentClass); AddButton("Export", PRS.Shared.Resources.download.AsBitmapImage(), SaveSchedules); AddButton("Import", PRS.Shared.Resources.upload.AsBitmapImage(), LoadSchedules); } public CoreTable Schedules { get; set; } public Type DocumentType { get; set; } public Guid DocumentID { get; set; } private bool LoadSchedules(Button sender, CoreRow[] rows) { if (rows.Length != 1) { MessageBox.Show("Please select only one row to process"); return false; } var row = rows.First(); var dlg = new OpenFileDialog(); dlg.Filter = "PRS Schedule Files (*.schedule)|*.schedule"; if (dlg.ShowDialog() == true) { Progress.Show(""); var json = File.ReadAllText(dlg.FileName); Schedule[] schedules = { }; try { schedules = Serialization.Deserialize(json); } catch (Exception e) { Progress.Close(); MessageBox.Show("[" + Path.GetFileName(dlg.FileName) + "] is not a valid schedule file!"); return false; } if (!schedules.Any()) { Progress.Close(); MessageBox.Show("[" + Path.GetFileName(dlg.FileName) + "] does not contain any schedules!"); return false; } foreach (var schedule in schedules) { schedule.DocumentID = DocumentID; schedule.DocumentClass = DocumentType.EntityName(); schedule.ID = Guid.Empty; schedule.Active = false; schedule.DueDate = DateTime.MinValue; } new Client().Save(schedules, "Imported from [" + Path.GetFileName(dlg.FileName) + "]"); Progress.Close(); MessageBox.Show(string.Format("{0} schedules loaded from [{1}]", schedules.Length, Path.GetFileName(dlg.FileName))); } return true; } private bool SaveSchedules(Button sender, CoreRow[] rows) { if (rows.Any()) { MessageBox.Show("Please select at least one schedule before Exporting!"); return false; } var names = new List(); rows.ForEach(r => names.Add(r.Get(c => c.Title))); var filename = DocumentType.Name + " (" + string.Join(" + ", names) + ")"; Path.GetInvalidFileNameChars().ForEach(c => filename = filename.Replace(c.ToString(), "")); Path.GetInvalidPathChars().ForEach(c => filename = filename.Replace(c.ToString(), "")); var dlg = new SaveFileDialog(); dlg.Filter = "PRS Schedule Files (*.schedule)|*.schedule"; dlg.FileName = filename + ".schedule"; dlg.AddExtension = false; if (dlg.ShowDialog() == true) { Progress.Show(""); Filter filter = null; foreach (var schedule in SelectedRows) if (filter == null) filter = new Filter(x => x.ID).IsEqualTo(schedule.Get(x => x.ID)); else filter = filter.Or(x => x.ID).IsEqualTo(schedule.Get(x => x.ID)); var schedules = new Client().Load(filter); foreach (var schedule in schedules) { schedule.DocumentID = DocumentID; schedule.DocumentClass = DocumentType.EntityName(); schedule.ID = Guid.Empty; schedule.Active = false; schedule.DueDate = DateTime.MinValue; } var json = Serialization.Serialize(schedules); File.WriteAllText(dlg.FileName + ".schedule", json); Progress.Close(); MessageBox.Show(string.Format("{0} schedules saved to [{1}]", SelectedRows.Length, Path.GetFileName(dlg.FileName))); } return false; } private bool CheckClick(CoreRow row) { var Due = row.Get(x => x.DueDate); if (Due.Equals(DateTime.MinValue)) { MessageBox.Show("Schedule must have a due date!"); return false; } using (var client = new Client()) { var schedule = client.Query( new Filter(x => x.ID).IsEqualTo(row.Get(x => x.ID)), new Columns(x => x.ID).Add(x => x.Active)).ToObjects().FirstOrDefault(); schedule.Active = !schedule.Active; client.Save(schedule, schedule.Active ? "Activated Schedule" : "Disabled Schedule"); } return true; } public override void ConfigureColumns(DynamicGridColumns columns /*, bool dolookups = true */) { var colDocType = columns.Where(x => x.ColumnName.Equals("DocumentType")).FirstOrDefault(); if (colDocType != null) columns.Remove(colDocType); var colRollover = columns.Where(x => x.ColumnName.Equals("Rollover")).FirstOrDefault(); if (colRollover != null) colRollover.Lookups = new Dictionary { { ScheduleRollover.FromActualDate, "From Actual" }, { ScheduleRollover.FromDueDate, "From Due" } }; var colPeriod = columns.Where(x => x.ColumnName.Equals("Period")).FirstOrDefault(); if (colPeriod != null) colPeriod.Lookups = new Dictionary { { SchedulePeriod.Year, "Years" }, { SchedulePeriod.Month, "Months" }, { SchedulePeriod.Week, "Weeks" }, { SchedulePeriod.Day, "Days" }, { SchedulePeriod.Hour, "Hours" }, { SchedulePeriod.Minute, "Minutes" } }; var colTrigger = columns.Where(x => x.ColumnName.Equals("Trigger")).FirstOrDefault(); if (colTrigger != null) colTrigger.Lookups = new Dictionary { { ScheduleTrigger.Distance, "Distance Travelled" }, { ScheduleTrigger.Usage, "Usage Time" }, { ScheduleTrigger.Counter1, "Counter 1" }, { ScheduleTrigger.Counter2, "Counter 2" }, { ScheduleTrigger.Counter3, "Counter 3" }, { ScheduleTrigger.Counter4, "Counter 4" }, { ScheduleTrigger.Counter5, "Counter 5" } }; var colScheduleType = columns.Where(x => x.ColumnName.Equals("ScheduleType")).FirstOrDefault(); if (colScheduleType != null) colScheduleType.Lookups = new Dictionary { { ScheduleType.Job, "Job" }, { ScheduleType.Task, "Task" } }; base.ConfigureColumns(columns /*,dolookups */); } //protected override void DeleteItem(DataRow row) //{ // Items.Remove(Items[row.Index]); //} //protected override ScheduleItem LoadItem(DataRow row) //{ // return Items[row.Index]; //} //protected override DataTable Reload(Dictionary criteria, List columns, string sort) //{ // criteria.Add("DocumentID", DocumentID); // return base.Reload(criteria, columns, sort); //} protected override void Reload(Filters criteria, Columns columns, ref SortOrder sort, Action action) { criteria.Add(new Filter(x => x.DocumentID).IsEqualTo(DocumentID)); sort = new SortOrder(x => x.DueDate); base.Reload(criteria, columns, ref sort, action); } protected override Schedule CreateItem() { if(DocumentType is null) { throw new Exception("Cannot create item when DocumentType is null."); } var schedule = base.CreateItem(); schedule.DocumentClass = DocumentType.EntityName(); schedule.DocumentID = DocumentID; if (DocumentType == typeof(CustomModule) || DocumentType == typeof(ScheduledScript)) schedule.ScheduleType = ScheduleType.None; return schedule; } public override void SaveItem(Schedule item) { if(DocumentType is not null) { item.DocumentClass = DocumentType.EntityName(); } else { if (string.IsNullOrWhiteSpace(item.DocumentClass)) { throw new Exception("Cannot save item when DocumentType is null."); } } base.SaveItem(item); } protected override void ReconfigureEditors(DynamicEditorGrid grid, Schedule[] items) { base.ReconfigureEditors(grid, items); var frequency = grid.FindEditor("Frequency"); if (frequency != null) { var freq = (int)frequency.GetValue("Frequency"); var period = grid.FindEditor("Period"); period?.SetEnabled(freq > 0); var due = grid.FindEditor("DueDate"); due?.SetEnabled(freq > 0); } var threshold = grid.FindEditor("Threshold"); if (threshold != null) { var thresh = (int)threshold.GetValue("Threshold"); var trigger = grid.FindEditor("Trigger"); trigger?.SetEnabled(thresh > 0); var next = grid.FindEditor("DueThreshold"); next?.SetEnabled(thresh > 0); } var scheduleTypeEditor = grid.FindEditor("ScheduleType"); if(scheduleTypeEditor != null) { var scheduleType = (ScheduleType)scheduleTypeEditor.GetValue("ScheduleType"); var taskTypeEditor = grid.FindEditor(nameof(Schedule.KanbanType)); taskTypeEditor?.SetEnabled(scheduleType == ScheduleType.Task); } } protected override Dictionary EditorValueChanged(IDynamicEditorForm editor, Schedule[] items, string name, object value) { return base.EditorValueChanged(editor, items, name, value); } protected override BaseEditor? GetEditor(object item, DynamicGridColumn column) { var types = new List { typeof(CustomModule), typeof(ScheduledScript), typeof(Employee), typeof(Equipment) }; var columns = new List { "ScheduleType" }; var schedule = (Schedule)item; var documentType = schedule.DocumentType(); if (documentType == typeof(CustomModule) || documentType == typeof(ScheduledScript)) columns.AddRange(new[] { "Description", "LeadTime", "EmployeeLink.ID", "ManagerLink.ID", "Report.ID", "Threshold", "Trigger", "DueThreshold", "Rollover", "QAForm" }); else if (documentType == typeof(Employee)) columns.AddRange(new[] { "Description", "EmployeeLink.ID", "Threshold", "Trigger", "DueThreshold" }); else if (documentType == typeof(Customer)) columns.AddRange(new[] { "Threshold", "Trigger", "DueThreshold" }); if (types.Contains(documentType) && columns.Contains(column.ColumnName)) return new NullEditor(); return base.GetEditor(item, column); } public override DynamicEditorPages LoadEditorPages(Schedule item) { var pages = base.LoadEditorPages(item); foreach (var page in pages.ToArray()) { if (page is IDynamicOneToManyGrid && item.ScheduleType != ScheduleType.Task) pages = new DynamicEditorPages(pages.Where(x => x != page)); else if (page is IDynamicOneToManyGrid && item.ScheduleType != ScheduleType.Job) pages = new DynamicEditorPages(pages.Where(x => x != page)); } return pages; } protected override void DefineLookups(ILookupEditorControl sender, Schedule[] items) { base.DefineLookups(sender, items); } } }