using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Linq.Expressions; using System.Windows; using System.Windows.Controls; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using Comal.Classes; using InABox.Clients; using InABox.Core; using InABox.WPF; using Microsoft.Win32; using PRSDesktop.WidgetGroups; using Syncfusion.UI.Xaml.Charts; using Syncfusion.XlsIO; namespace PRSDesktop { public class FactoryProductivityDashboardProperties : IDashboardProperties { public string Test { get; set; } = "Untitled"; } public class FactoryProductivityDashboardElement : DashboardElement { } /// /// Interaction logic for FactoryProductivity.xaml /// public partial class FactoryProductivityDashboard : UserControl, IPanel, IDashboardWidget { public enum HistoryView { Day, Week, Month, Year } public enum ItemsGroup { Packet, Setout, Job } public enum StaffGroup { Employee, Section } private readonly BitmapImage back = PRSDesktop.Resources.back.AsBitmapImage(32, 32); private HistoryViewModel history; private readonly BitmapImage next = PRSDesktop.Resources.next.AsBitmapImage(32, 32); public FactoryProductivityDashboard() { InitializeComponent(); PrevDay.Content = new Image { Source = back }; NextDay.Content = new Image { Source = next }; } public bool IsReady { get; set; } public event DataModelUpdateEvent OnUpdateDataModel; public void CreateToolbarButtons(IPanelHost host) { } public string SectionName => "Factory Productivity"; public FactoryProductivityDashboardProperties Properties { get; set; } public DataModel DataModel(Selection selection) { if (history.To == DateTime.MinValue) history.To = DateTime.Today; return new AutoDataModel(history.GetFilter()); } public void Refresh() { if (history.To == DateTime.MinValue) history.To = DateTime.Today; if (history.View == HistoryView.Day) CurrentDate.Text = string.Format("{0:ddd, dd MMMM yyyy}", history.To); else CurrentDate.Text = string.Format("{0:dd MMM yy} - {1:dd MMM yy}", history.From, history.To); //List colors = new List(); //var props = typeof(Colors).GetProperties(System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public).Where(x => x.PropertyType == typeof(Color)); //foreach (var prop in props) //{ // Color color = (Color)prop.GetValue(null); // if ((color != Colors.Transparent) && (color.R < color.G) && (color.R < color.B)) // colors.Add(color); //} Hours.Series.Clear(); foreach (var key in history.Items.Keys) { var comps = key.Split('|'); var seriesdata = history.Items[key]; var series = new StackingColumnSeries(); series.ShowTooltip = true; series.TooltipTemplate = Hours.Resources["tooltipTemplate"] as DataTemplate; series.ItemsSource = seriesdata; series.XBindingPath = "Name"; series.YBindingPath = "Hours"; series.Label = comps[1]; //int colorindex = Hours.Series.Count % colors.Count; //var color = colors[colorindex]; var color = Colors.Transparent; try { color = (Color)ColorConverter.ConvertFromString(comps[0]); } catch (Exception e) { Logger.Send(LogType.Error, "", string.Format("*** Unknown Error: {0}\n{1}", e.Message, e.StackTrace)); } series.Interior = new SolidColorBrush(color); series.Stroke = new SolidColorBrush(Colors.Black); series.StrokeThickness = 0.75F; series.BorderBrush = new SolidColorBrush(Colors.Black); series.BorderThickness = new Thickness(0.75F, 0.75F, 00.75F, 0.0F); series.MouseDoubleClick += (o, e) => { foreach (var other in Hours.Series.Where(x => x != series)) other.Visibility = other.Visibility == Visibility.Collapsed ? Visibility.Visible : Visibility.Collapsed; }; Hours.Series.Add(series); } } public Dictionary Selected() { return new Dictionary(); } public void Setup() { history = new HistoryViewModel(); DataContext = history; var legends = new ChartLegendCollection(); Hours.Legend = new ChartLegend { LegendPosition = LegendPosition.Outside, DockPosition = ChartDock.Top, //FontSize = 11, ItemsPanel = Hours.Resources["itemPanelTemplate"] as ItemsPanelTemplate, CheckBoxVisibility = Visibility.Visible, ToggleSeriesVisibility = true }; } public void Shutdown() { } public void Heartbeat(TimeSpan time) { } private void CurrentDate_MouseDoubleClick(object sender, MouseButtonEventArgs e) { history.To = DateTime.Today; Refresh(); } private void PrevDay_Click(object sender, RoutedEventArgs e) { history.Back(); Refresh(); } private void NextDay_Click(object sender, RoutedEventArgs e) { history.Forward(); Refresh(); } private void ViewStyle_SelectionChanged(object sender, SelectionChangedEventArgs e) { if (history == null) return; history.View = ViewStyle.SelectedIndex == 0 ? HistoryView.Day : ViewStyle.SelectedIndex == 1 ? HistoryView.Week : ViewStyle.SelectedIndex == 2 ? HistoryView.Month : HistoryView.Year; Refresh(); } private void StaffView_SelectionChanged(object sender, SelectionChangedEventArgs e) { if (history == null) return; history.StaffGroup = StaffView.SelectedIndex == 0 ? StaffGroup.Employee : StaffGroup.Section; Refresh(); } private void ItemsView_SelectionChanged(object sender, SelectionChangedEventArgs e) { if (history == null) return; history.ItemsGroup = ItemsView.SelectedIndex == 0 ? ItemsGroup.Packet : ItemsView.SelectedIndex == 1 ? ItemsGroup.Setout : ItemsGroup.Job; Refresh(); } private void Search_KeyUp(object sender, KeyEventArgs e) { if (string.IsNullOrWhiteSpace(Search.Text) || e.Key == Key.Return) { history.Search = Search.Text; Refresh(); } } private void Export_Click(object sender, RoutedEventArgs e) { var excelEngine = new ExcelEngine(); var application = excelEngine.Excel; var myWorkbook = excelEngine.Excel.Workbooks.Add(); myWorkbook.Version = ExcelVersion.Excel2007; var mySheet = myWorkbook.Worksheets[0]; var iCol = 2; foreach (var key in history.Items.Keys) { mySheet.Range[1, iCol].Text = key; var records = history.Items[key]; var iRow = 2; foreach (var record in records) { mySheet.Range[iRow, 1].Text = record.Name; mySheet.Range[iRow, iCol].Number = Math.Truncate(record.Hours * 100.0F) / 100.0F; iRow++; } iCol++; } mySheet.UsedRange.AutofitColumns(); foreach (var col in mySheet.UsedRange.Columns) col.ColumnWidth += 5; foreach (var row in mySheet.UsedRange.Rows) { row.RowHeight += 5; row.VerticalAlignment = ExcelVAlign.VAlignCenter; } var dlg = new SaveFileDialog(); dlg.Filter = "Excel Files (*.xlsx)|*.xlsx"; dlg.FileName = "Factory KPI Screen.xlsx"; if (dlg.ShowDialog() == true) try { myWorkbook.SaveAs(dlg.FileName, ExcelSaveType.SaveAsXLS); Process.Start(new ProcessStartInfo(dlg.FileName) { UseShellExecute = true }); } catch (Exception e2) { MessageBox.Show("Error saving spreadhseet!\n\n" + e2.Message); } } public class History { public string Name { get; set; } //public int QAPackets { get; set; } public int Packets { get; set; } //public double QAHours { get; set; } public double Hours { get; set; } public double LostTime { get; set; } } public class HistoryViewModel { private ItemsGroup _itemsgroup = ItemsGroup.Job; private string _search = ""; private StaffGroup _staffgroup = StaffGroup.Employee; private DateTime _to = DateTime.MinValue; private HistoryView _view = HistoryView.Day; public HistoryViewModel() { Staff = new List(); Items = new Dictionary>(); } public StaffGroup StaffGroup { get => _staffgroup; set { _staffgroup = value; Refresh(); } } public List Staff { get; } public ItemsGroup ItemsGroup { get => _itemsgroup; set { _itemsgroup = value; Refresh(); } } // Key = series public Dictionary> Items { get; set; } public HistoryView View { get => _view; set { _view = value; Refresh(); } } public DateTime To { get => _to.Date; set { _to = value; Refresh(); } } public DateTime From => _view.Equals(HistoryView.Day) ? _to : _view.Equals(HistoryView.Week) ? _to.AddDays(-6) : _view.Equals(HistoryView.Month) ? _to.AddMonths(-1).AddDays(1) : _to.AddYears(-1).AddDays(1); public string Search { get => _search; set { _search = value; Refresh(); } } public void Forward() { To = _view.Equals(HistoryView.Day) ? _to.AddDays(1) : _view.Equals(HistoryView.Week) ? _to.AddDays(7) : _view.Equals(HistoryView.Month) ? _to.AddMonths(1) : _to.AddYears(1); } public void Back() { To = _view.Equals(HistoryView.Day) ? _to.AddDays(-1) : _view.Equals(HistoryView.Week) ? _to.AddDays(-7) : _view.Equals(HistoryView.Month) ? _to.AddMonths(-1) : _to.AddYears(-1); } private void AddSearchCriteria(Filter filter, string search, params Expression>[] expressions) { var comps = search.Trim().Split(' '); foreach (var comp in comps) { Filter result = null; foreach (var expression in expressions) result = result == null ? new Filter(expression).Contains(comp) : result.Or(expression).Contains(comp); filter.Ands.Add(result); } } public Filter GetFilter() { var from = _view.Equals(HistoryView.Day) ? _to.AddDays(-1) : _view.Equals(HistoryView.Week) ? _to.AddDays(-7) : _view.Equals(HistoryView.Month) ? _to.AddMonths(-1) : _to.AddYears(-1); var criteria = new Filter(x => x.Date).IsGreaterThan(from).And(x => x.Date).IsLessThanOrEqualTo(_to); if (!string.IsNullOrWhiteSpace(_search)) { criteria = criteria.TextSearch( Search, x => x.Packet.SetoutLink.JobLink.JobNumber, x => x.Packet.SetoutLink.JobLink.Name, x => x.Packet.SetoutLink.Number, x => x.Packet.SetoutLink.Description, //x => x.Packet.SetoutLink.Reference, x => x.Packet.SetoutLink.Location, x => x.Packet.Serial, x => x.Packet.Location, x => x.Packet.Title, x => x.LostTime.Description ); } return criteria; } private void Refresh() { var criteria = GetFilter(); var data = new Client().Query( criteria, null, new SortOrder(x => x.Employee.Name) ); Staff.Clear(); foreach (var row in data.Rows) { var staff = _staffgroup.Equals(StaffGroup.Employee) ? row.Get(x => x.Employee.Name) : row.Get(x => x.Section.Name); var record = Staff.FirstOrDefault(x => string.Equals(x.Name, staff)); if (record == null) { record = new History { Name = staff }; Staff.Add(record); } var hrs = row.Get(x => x.QADuration).TotalHours + row.Get(x => x.WorkDuration).TotalHours; if (Entity.IsEntityLinkValid(x => x.Packet, row)) record.Hours += hrs; else record.LostTime += hrs; record.Packets += row.Get(x => x.WorkCompleted); } Items.Clear(); foreach (var row in data.Rows) { var staff = _staffgroup.Equals(StaffGroup.Employee) ? row.Get(x => x.Employee.Name) : row.Get(x => x.Section.Name); var packet = ""; if (row.IsEntityLinkValid(x => x.Packet)) packet = row.Get(x => x.Packet.SetoutLink.JobLink.Color) + "|" + (_itemsgroup.Equals(ItemsGroup.Packet) ? row.Get(x => x.Packet.Serial) : _itemsgroup.Equals(ItemsGroup.Setout) ? row.Get(x => x.Packet.SetoutLink.Number) : row.Get(x => x.Packet.SetoutLink.JobLink.JobNumber)); //row.Get(x => x.Job.Number).ToString(); else if (row.IsEntityLinkValid(x => x.LostTime)) packet = "#FF00FF00|" + row.Get(x => x.LostTime.Description); else packet = "#FFFF0000|Lost Time"; if (!Items.ContainsKey(packet)) { var records = new List(); foreach (var _staff in Staff) records.Add(new History { Name = _staff.Name }); Items[packet] = records; } var record = Items[packet].FirstOrDefault(x => string.Equals(x.Name, staff)); record.Packets = record.Packets + row.Get(x => x.WorkCompleted); record.Hours = record.Hours + row.Get(x => x.QADuration).TotalHours + row.Get(x => x.WorkDuration).TotalHours; } } } } }