using System; using System.Collections; using System.Collections.Generic; using System.Data; using System.Diagnostics; using System.Globalization; using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Text.RegularExpressions; using System.Threading; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Input; using Comal.Classes; using InABox.Clients; using InABox.Core; using InABox.DynamicGrid; using InABox.Reports; using InABox.Reports.Common; using InABox.WPF; using PRSDesktop.Forms; using PRSDesktop.WidgetGroups; using Syncfusion.UI.Xaml.Grid; using Syncfusion.UI.Xaml.Grid.Converter; using Syncfusion.Windows.Shared; using Syncfusion.XlsIO; using SelectionChangedEventArgs = System.Windows.Controls.SelectionChangedEventArgs; namespace PRSDesktop { internal class MileStoneImageConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { return Equals(value, DateTime.MinValue) ? null : Resources.milestone.AsBitmapImage(); } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { return null; } } /// /// Interaction logic for QADashboard.xaml /// public partial class QADashboard : UserControl, IPanel { private bool _changing; private DateTime _from; private string _search = ""; private DateTime _to; private CoreTable allforms; private readonly Dictionary QuestionCodes = new(); public bool IsReady { get; set; } public event DataModelUpdateEvent OnUpdateDataModel; private static readonly Dictionary>> parentColumns = new() { { typeof(Kanban), new() { new("Parent.Number", "Task No") } }, { typeof(Job), new() { new("Parent.JobNumber", "Job No") } }, { typeof(JobITP), new() { new("Parent.Code", "Code") } }, { typeof(Assignment), new() { new("Parent.Number", "Ass. No") } }, { typeof(TimeSheet), new() { } }, { typeof(LeaveRequest), new() { } }, { typeof(Employee), new() { new("Parent.Code", "Employee") } }, { typeof(PurchaseOrderItem), new() { new("Parent.PONumber", "PO No") } }, }; private Type? parentType; private Type? formType; #region DataGrid Configuration private void DataGrid_AutoGeneratingColumn(object sender, AutoGeneratingColumnArgs e) { e.Column.TextAlignment = TextAlignment.Center; e.Column.HorizontalHeaderContentAlignment = HorizontalAlignment.Center; e.Column.ColumnSizer = GridLengthUnitType.None; var value = e.Column.ValueBinding as Binding; if (value.Path.Path.Equals("ID") || value.Path.Path.Equals("Form_ID") || value.Path.Path.Equals("Parent_ID") || value.Path.Path.Equals("FormData") || value.Path.Path.Equals("Location_Latitude") || value.Path.Path.Equals("Location_Longitude")) { e.Cancel = true; } else if (value.Path.Path.Equals("Location_Timestamp")) { e.Column = new GridImageColumn(); e.Column.Width = dataGrid.RowHeight; e.Column.HeaderStyle = Resources["TemplateHeaderStyle"] as Style; e.Column.HeaderText = ""; e.Column.Padding = new Thickness(4); e.Column.ValueBinding = new Binding { Path = new PropertyPath(value.Path.Path), Converter = new MileStoneImageConverter() }; e.Column.MappingName = "Location.Timestamp"; } else if (parentColumns.TryGetValue(parentType, out var pColumns) && pColumns.Any(x => x.Item2.Equals(value.Path.Path))) { e.Column.ColumnSizer = GridLengthUnitType.Auto; e.Column.HeaderStyle = Resources["TemplateHeaderStyle"] as Style; } else if (value.Path.Path.Equals("Job No")) { e.Column.Width = 60; e.Column.HeaderStyle = Resources["TemplateHeaderStyle"] as Style; } else if (value.Path.Path.Equals("Description")) { e.Column.TextAlignment = TextAlignment.Left; e.Column.HorizontalHeaderContentAlignment = HorizontalAlignment.Left; e.Column.Width = 450; e.Column.HeaderStyle = Resources["TemplateHeaderStyle"] as Style; } else if (value.Path.Path.Equals("Completed")) { e.Column.Width = 100; e.Column.HeaderStyle = Resources["TemplateHeaderStyle"] as Style; (e.Column as GridDateTimeColumn).Pattern = DateTimePattern.CustomPattern; (e.Column as GridDateTimeColumn).CustomPattern = "dd MMM yy hh:mm"; } else if (value.Path.Path.Equals("Completed By")) { e.Column.Width = 100; e.Column.HeaderStyle = Resources["TemplateHeaderStyle"] as Style; } else if (value.Path.Path.Equals("Processed")) { e.Column.Width = 100; e.Column.HeaderStyle = Resources["TemplateHeaderStyle"] as Style; } else { var data = dataGrid.ItemsSource as DataTable; //int index = data.Columns.IndexOf(e.Column.MappingName) - 2; //Style style = new Style(typeof(GridCell)); //e.Column.CellStyle = style; e.Column.Width = 100; e.Column.HeaderStyle = Resources["TemplateHeaderStyle"] as Style; e.Column.HeaderText = QuestionCodes[e.Column.MappingName]; } } #endregion private Entity? GetEntityForm(Guid id) where T : Entity, IDigitalFormInstance, IRemotable, IPersistent, new() { var columns = DynamicFormEditWindow.FormColumns(); return new Client().Query( new Filter(x => x.ID).IsEqualTo(id), columns).Rows.FirstOrDefault()?.ToObject(); } private void SaveEntityForm(T entityForm) where T : Entity, IDigitalFormInstance, IRemotable, IPersistent, new() { new Client().Save(entityForm, "Edited by user"); } private void DataGrid_CellDoubleTapped(object sender, GridCellDoubleTappedEventArgs e) { if (e.RowColumnIndex.RowIndex == 0) return; var table = dataGrid.ItemsSource as DataTable; var formid = (Guid)table.Rows[e.RowColumnIndex.RowIndex - 1]["Form_ID"]; var formdata = (string)table.Rows[e.RowColumnIndex.RowIndex - 1]["FormData"]; var id = (Guid)table.Rows[e.RowColumnIndex.RowIndex - 1]["ID"]; if (formType == null) return; var entityForm = typeof(QADashboard) .GetMethod(nameof(GetEntityForm), System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)! .MakeGenericMethod(formType) .Invoke(this, new object[] { id }) as IDigitalFormInstance; if (entityForm != null) { if (DynamicFormEditWindow.EditDigitalForm(entityForm, out var dataModel)) { dataModel.Update(null); /*typeof(QADashboard) .GetMethod(nameof(SaveEntityForm), System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)! .MakeGenericMethod(formType) .Invoke(this, new object[] { entityForm });*/ Refresh(); } } /* var query = new MultiQuery(); query.Add( new QueryDef( new Filter(x => x.Form.ID).IsEqualTo(formid), null, null ), typeof(DigitalFormVariable) ); query.Add( new QueryDef( new Filter(x => x.Form.ID).IsEqualTo(formid).And(x => x.Active).IsEqualTo(true), null, null ), typeof(DigitalFormLayout) ); query.Query(); var variables = query.Get(typeof(DigitalFormVariable)).Rows.Select(x => x.ToObject()); var layout = query.Get(typeof(DigitalFormLayout)).Rows.FirstOrDefault()?.ToObject(); if (layout == null) { MessageBox.Show("No Active Layouts Found!"); return; } var form = new DynamicFormWindow(); form.Designing = false; form.HideViewButton = true; form.ReadOnly = true; form.Variables = variables.ToArray(); form.Type = layout.Type; var f = new DFLayout(); if (!string.IsNullOrWhiteSpace(layout.Layout)) { f.LoadLayout(layout.Layout); } else { f = new DFLayout(); f.RowHeights.Add("Auto"); f.ColumnWidths.AddRange(new[] { "*", "Auto" }); } f.LoadVariables(variables); form.Form = f; if (!string.IsNullOrWhiteSpace(formdata)) form.Values = Serialization.Deserialize>(formdata); form.ShowDialog();*/ } private void DataGrid_CellTapped(object sender, GridCellTappedEventArgs e) { if (e.RowColumnIndex.ColumnIndex == 0) { var timestamp = (DateTime)(e.Record as DataRowView).Row["Location_Timestamp"]; var latitude = (double)(e.Record as DataRowView).Row["Location_Latitude"]; var longitude = (double)(e.Record as DataRowView).Row["Location_Longitude"]; var form = new MapForm(latitude, longitude, timestamp); form.ShowDialog(); } } #region IPanel Interface public QADashboard() { _from = DateTime.Today; _to = DateTime.Today; InitializeComponent(); SetDates(_from, _to, false); } public void CreateToolbarButtons(IPanelHost host) { } public void Setup() { var query = new MultiQuery(); query.Add( new QueryDef( new Filter(x => x.Active).IsEqualTo(true), null, null ), typeof(DigitalForm) ); query.Add( new QueryDef( LookupFactory.DefineFilter(), new Columns(x => x.ID, x => x.JobNumber, x => x.Name), null ), typeof(Job) ); query.Query(); allforms = query.Get(typeof(DigitalForm)); var cats = new DigitalFormCategoryLookups(null); cats.OnAfterGenerateLookups += (sender, entries) => { entries.Insert(0, new LookupEntry("", "Select Category")); }; Category.ItemsSource = cats.AsTable("AppliesTo").ToDictionary("AppliesTo", "Display"); var jobs = query.Get(typeof(Job)); var alljobs = jobs.NewRow(); alljobs.Set(x => x.ID, Guid.Empty); alljobs.Set(x => x.JobNumber, "ALL"); alljobs.Set(x => x.Name, "All Jobs"); jobs.Rows.Insert(0, alljobs); Jobs.ItemsSource = jobs.ToDictionary(x => x.ID, new Expression>[] { x => x.JobNumber, x => x.Name }, x => x.JobNumber); //Dictionary joblist = new Dictionary() { { Guid.Empty, "All Jobs" } }; //CoreTable jobs = new Client().Query( // LookupFactory.DefineFilter(), // LookupFactory.DefineColumns(), // LookupFactory.DefineSort() //); //foreach (var row in jobs.Rows) //{ // //if (row.Get(x => x.Group.Description).Equals("FACTORY")) // joblist[row.Get(x => x.ID)] = String.Format("{0} - {1}", row.Get(x => x.JobNumber), row.Get(x => x.Name)); //} //Jobs.ItemsSource = joblist; } public void Shutdown() { } public string GetJobLink(string prefix, Type type) { var props = type.GetProperties().Where(x => x.PropertyType.BaseType != null && x.PropertyType.BaseType.IsGenericType && x.PropertyType.BaseType.GetGenericTypeDefinition() == typeof(EntityLink<>)); foreach (var prop in props) { if (prop.PropertyType == typeof(JobLink)) return (string.IsNullOrEmpty(prefix) ? "" : prefix + ".") + prop.Name; var result = GetJobLink((string.IsNullOrEmpty(prefix) ? "" : prefix + ".") + prop.Name, prop.PropertyType); if (!string.IsNullOrEmpty(result)) return result; } return ""; } public Type CategoryToType(string category) { var instances = CoreUtils.TypeList( AppDomain.CurrentDomain.GetAssemblies(), x => !x.IsAbstract && x.GetInterfaces().Contains(typeof(IDigitalFormInstance)) ).ToArray(); foreach (var instance in instances) { var interfaces = instance.GetInterfaces() .Where(x => x.IsGenericType && x.GetGenericTypeDefinition().Equals(typeof(IDigitalFormInstance<>))); var links = interfaces.Select(x => x.GenericTypeArguments.First()); var link = links.FirstOrDefault(l => l.GetInheritedGenericTypeArguments().Any(i => string.Equals(i.Name, category))); if (link != null) { return instance; } } return null; } public void Refresh() { Progress.Show("Refreshing"); try { qaGrid.Clear(); qaGrid.LoadChecks("", new QAQuestion[] { }, new Dictionary()); dataGrid.ItemsSource = null; var category = Category.SelectedValue as string; if (string.IsNullOrWhiteSpace(category)) { DigitalFormsDock.Visibility = Visibility.Collapsed; qaGrid.Visibility = Visibility.Collapsed; dataGrid.Visibility = Visibility.Collapsed; return; } var form = (KeyValuePair)Form.SelectedItem; if (form.Key == Guid.Empty) { DigitalFormsDock.Visibility = Visibility.Collapsed; qaGrid.Visibility = Visibility.Collapsed; dataGrid.Visibility = Visibility.Collapsed; return; } var type = CategoryToType(category); if (type == null) return; formType = type; parentType = CoreUtils.TypeList( AppDomain.CurrentDomain.GetAssemblies(), x => !x.IsAbstract && string.Equals(x.Name, category) ).FirstOrDefault(); var parentcols = LookupFactory.DefineColumns(parentType); Progress.SetMessage("Loading Data"); var jobid = Jobs.SelectedValue != null ? (Guid)Jobs.SelectedValue : Guid.Empty; var isEntityForm = type.IsSubclassOfRawGeneric(typeof(EntityForm<,>)); var query = new MultiQuery(); query.Add( new QueryDef( new Filter(x => x.Form.ID).IsEqualTo(form.Key), null, null ), typeof(QAQuestion) ); query.Add( new QueryDef( new Filter(x => x.Form.ID).IsEqualTo(form.Key), null, new SortOrder(x => x.Sequence) ), typeof(DigitalFormVariable) ); var columns = LookupFactory.DefineColumns(type); var sort = LookupFactory.DefineSort(type); var JobLink = GetJobLink("", type); var filtertype = typeof(Filter<>).MakeGenericType(type); var filter = Activator.CreateInstance(typeof(Filter<>).MakeGenericType(type)); CoreUtils.SetPropertyValue(filter, "Expression", CoreUtils.GetMemberExpression(type, "FormCompleted")); CoreUtils.SetPropertyValue(filter, "Operator", Operator.IsGreaterThanOrEqualTo); CoreUtils.SetPropertyValue(filter, "Value", _from); var ands = filtertype.GetProperty("Ands").GetValue(filter) as IList; var to = Activator.CreateInstance(filtertype); CoreUtils.SetPropertyValue(to, "Expression", CoreUtils.GetMemberExpression(type, "FormCompleted")); CoreUtils.SetPropertyValue(to, "Operator", Operator.IsLessThan); CoreUtils.SetPropertyValue(to, "Value", _to.AddDays(1)); ands.Add(to); var formid = Activator.CreateInstance(filtertype); CoreUtils.SetPropertyValue(formid, "Expression", CoreUtils.GetMemberExpression(type, "Form.ID")); CoreUtils.SetPropertyValue(formid, "Operator", Operator.IsEqualTo); CoreUtils.SetPropertyValue(formid, "Value", form.Key); ands.Add(formid); if (jobid != Guid.Empty) { var job = Activator.CreateInstance(filtertype); CoreUtils.SetPropertyValue(job, "Expression", CoreUtils.GetMemberExpression(type, JobLink + ".ID")); CoreUtils.SetPropertyValue(job, "Operator", Operator.IsEqualTo); CoreUtils.SetPropertyValue(job, "Value", jobid); ands.Add(job); } var colstype = typeof(Columns<>).MakeGenericType(type); var cols = Activator.CreateInstance(colstype) as IColumns; cols.Add("ID"); foreach (var col in parentcols.ColumnNames()) cols.Add("Parent." + col); if(parentColumns.TryGetValue(parentType, out var pColumns)) { foreach(var (field, name) in pColumns) { cols.Add(field); } } cols.Add("Form.ID"); cols.Add("FormData"); cols.Add("FormCompleted"); cols.Add("FormCompletedBy.UserID"); if(isEntityForm) cols.Add("Processed"); cols.Add("Location.Timestamp"); cols.Add("Location.Latitude"); cols.Add("Location.Longitude"); if (!string.IsNullOrWhiteSpace(JobLink)) cols.Add(JobLink + ".JobNumber"); var querytype = typeof(QueryDef<>).MakeGenericType(type); query.Add(Activator.CreateInstance(querytype, filter, cols, sort) as IQueryDef, type); if(parentType == typeof(JobITP)) { query.Add( new Filter(x => x.ID).InQuery(filter as Filter, x => x.Parent.ID), new Columns(x => x.ID, x => x.Job.JobNumber)); } query.Query(); var questions = query.Get(typeof(QAQuestion)); // new Client().Query(new Filter(x => x.QAForm.ID).IsEqualTo(form.Key)); var variables = query.Get(typeof(DigitalFormVariable)).Rows.Select(x => x.ToObject()).ToArray(); var formdata = query.Get(type); var data = new DataTable(); data.Columns.Add("ID", typeof(Guid)); data.Columns.Add("Form_ID", typeof(Guid)); data.Columns.Add("Parent_ID", typeof(Guid)); data.Columns.Add("Location_Timestamp", typeof(DateTime)); data.Columns.Add("Location_Latitude", typeof(double)); data.Columns.Add("Location_Longitude", typeof(double)); data.Columns.Add("FormData", typeof(string)); if (parentType == typeof(JobITP)) { data.Columns.Add("Job No", typeof(string)); } if (pColumns != null) { foreach (var (field, name) in pColumns) { data.Columns.Add(name, typeof(string)); } } data.Columns.Add("Description", typeof(string)); data.Columns.Add("Completed", typeof(DateTime)); data.Columns.Add("Completed By", typeof(string)); if(isEntityForm) data.Columns.Add("Processed", typeof(bool)); if (variables.Any()) { foreach (var variable in variables) { var code = variable.Code.Replace("/", " "); QuestionCodes[code] = Thread.CurrentThread.CurrentCulture.TextInfo.ToTitleCase(code.ToLower()); data.Columns.Add(code, typeof(string)); } } else if (questions.Rows.Any()) { Progress.SetMessage("Loading Checks"); qaGrid.Clear(); qaGrid.LoadChecks(form.Value, questions.Rows.Select(x => x.ToObject()), new Dictionary()); qaGrid.CollapseMargins(); var i = 1; foreach (var row in questions.Rows) { var id = row.Get(x => x.ID).ToString(); if (!row.Get(x => x.Answer).Equals(QAAnswer.Comment)) { data.Columns.Add(id, typeof(string)); var code = row.Get(x => x.Code); QuestionCodes[id] = string.IsNullOrEmpty(code) ? string.Format("{0}.", i) : code; i++; } } } foreach (var row in formdata.Rows) { var qadata = row["FormData"] != null ? row["FormData"].ToString() : ""; if (!string.IsNullOrWhiteSpace(qadata)) { var datarow = data.NewRow(); datarow["ID"] = (Guid)row["ID"]; datarow["Form_ID"] = (Guid)row["Form.ID"]; datarow["Parent_ID"] = (Guid)row["Parent.ID"]; datarow["Location_Timestamp"] = (DateTime)row["Location.Timestamp"]; datarow["Location_Latitude"] = (double)row["Location.Latitude"]; datarow["Location_Longitude"] = (double)row["Location.Longitude"]; datarow["FormData"] = (string)row["FormData"]; var desc = new List(); foreach (var col in parentcols.ColumnNames().Where(x => x != "ID")) { var val = row["Parent." + col]; if (val != null && val.GetType() != typeof(Guid)) desc.Add(val.ToString()); } datarow["Description"] = string.Join(" : ", desc); datarow["Completed"] = (DateTime)row["FormCompleted"]; datarow["Completed By"] = (string)row["FormCompletedBy.UserID"]; if(isEntityForm) datarow["Processed"] = (bool)row["Processed"]; if(parentType == typeof(JobITP)) { var jobITP = query.Get().Rows.FirstOrDefault(x => (Guid)x["ID"] == (Guid)row["Parent.ID"]); datarow["Job No"] = jobITP?["Job.JobNumber"]; } if (pColumns != null) { foreach (var (field, name) in pColumns) { datarow[name] = row[field].ToString(); } } //datarow["Job No"] = (String)row[JobLink + ".JobNumber"]; var bHasData = false; if (variables.Any()) { var dict = Serialization.Deserialize>(qadata); foreach (var key in dict.Keys) { var variable = variables.FirstOrDefault(x => string.Equals(key, x.Code)); if (variable != null) { var value = variable.ParseValue(dict[key]); object format = variable.FormatValue(value); var sKey = key.Replace("/", " "); if (data.Columns.Contains(sKey)) { datarow[sKey] = format; bHasData = true; } } } } else { var dict = Serialization.Deserialize>(qadata); foreach (var key in dict.Keys) if (data.Columns.Contains(key.ToString())) { datarow[key.ToString()] = dict[key]; bHasData = true; } } if (bHasData) data.Rows.Add(datarow); } } dataGrid.ItemsSource = data; qaGrid.Visibility = !variables.Any() && questions.Rows.Any() ? Visibility.Visible : Visibility.Collapsed; dataGrid.Visibility = Visibility.Visible; } finally { Progress.Close(); } } public string? SectionName { get { var form = (KeyValuePair)Form.SelectedItem; if (Category.SelectedValue != null && form.Key != Guid.Empty) { return form.Key.ToString(); } return "Digital Forms"; } } public DataModel DataModel(Selection selection) { Type formtype = CategoryToType(Category.SelectedValue as String); var form = (KeyValuePair)Form.SelectedItem; if (formtype != null && form.Key != Guid.Empty) { IFilter filter; switch (selection) { case Selection.Selected: var formids = dataGrid.SelectedItems.Select(x => (x as DataRowView).Row["ID"]).ToArray(); filter = (Activator.CreateInstance(typeof(Filter<>).MakeGenericType(formtype)) as IFilter)!; filter.Expression = CoreUtils.CreateMemberExpression(formtype, "ID"); filter.Operator = Operator.InList; filter.Value = formids; break; case Selection.All: filter = Filter.Create(formtype).All(); break; case Selection.None: default: filter = (Activator.CreateInstance(typeof(Filter<>).MakeGenericType(formtype)) as IFilter)!.None(); break; } return (Activator.CreateInstance(typeof(DigitalFormReportDataModel<>)! .MakeGenericType(formtype), new object?[] { filter, form.Key }) as DataModel)!; } return new AutoDataModel(new Filter().None()); } public Dictionary Selected() { return new Dictionary(); } public void Heartbeat(TimeSpan time) { } #endregion #region Toolbar Handling private void Category_SelectionChanged(object sender, SelectionChangedEventArgs e) { _changing = true; var category = Category.SelectedValue as string; var type = CategoryToType(category); var JobLink = type != null ? GetJobLink("", type) : ""; if (string.IsNullOrWhiteSpace(JobLink)) { Jobs.SelectedValue = Guid.Empty; Jobs.IsEnabled = false; } else { Jobs.IsEnabled = true; } var forms = new Dictionary { { Guid.Empty, "" } }; if (!string.IsNullOrWhiteSpace(category)) { forms[Guid.Empty] = "Select Form"; var rows = allforms.Rows.Where(r => string.Equals(r.Get(c => c.AppliesTo), category)); foreach (var row in rows) forms[row.Get(x => x.ID)] = row.Get(x => x.Description); } Form.ItemsSource = forms; _changing = false; Form.SelectedIndex = 0; Form.IsEnabled = !string.IsNullOrWhiteSpace(category); OnUpdateDataModel?.Invoke(SectionName, DataModel(Selection.None)); } private void Form_SelectionChanged(object sender, SelectionChangedEventArgs e) { if (IsReady && !_changing) { Refresh(); OnUpdateDataModel?.Invoke(SectionName, DataModel(Selection.None)); } } private void Jobs_SelectionChanged(object sender, SelectionChangedEventArgs e) { if (IsReady && !_changing) Refresh(); } private int WeekDay(DateTime date) { if (date.DayOfWeek == DayOfWeek.Sunday) return 7; return (int)date.DayOfWeek - 1; } private void SetDates(DateTime? from, DateTime? to, bool enable) { if (_changing) return; _changing = true; _from = from.HasValue ? from.Value : DateTime.Today; FromDate.SelectedDate = from; FromDate.IsEnabled = enable; _to = to.HasValue ? to.Value : DateTime.Today; ToDate.SelectedDate = to; ToDate.IsEnabled = enable; _changing = false; if (!enable) Refresh(); } private void DateRange_SelectionChanged(object sender, SelectionChangedEventArgs e) { if (!IsReady) return; if (DateRange.SelectedIndex == 0) // Week To Date SetDates(DateTime.Today, DateTime.Today, false); else if (DateRange.SelectedIndex == 1) // Week To Date SetDates(DateTime.Today.AddDays(-1), DateTime.Today.AddDays(-1), false); else if (DateRange.SelectedIndex == 2) // Week To Date SetDates(DateTime.Today.AddDays(0 - WeekDay(DateTime.Today)), DateTime.Today, false); else if (DateRange.SelectedIndex == 3) // Last 7 Days SetDates(DateTime.Today.AddDays(-6), DateTime.Today, false); else if (DateRange.SelectedIndex == 4) // Month To Date SetDates(new DateTime(DateTime.Today.Year, DateTime.Today.Month, 1), DateTime.Today, false); else if (DateRange.SelectedIndex == 5) // Last 30 days SetDates(DateTime.Today.AddDays(-29), DateTime.Today, false); else if (DateRange.SelectedIndex == 6) // Year To Date SetDates(new DateTime(DateTime.Today.Year, 1, 1), DateTime.Today, false); else if (DateRange.SelectedIndex == 7) // Last 12 Months SetDates(DateTime.Today.AddYears(-1).AddDays(1), DateTime.Today, false); else if (DateRange.SelectedIndex == 8) // Custom SetDates(FromDate.SelectedDate.Value, ToDate.SelectedDate.Value, true); } private void FromDate_SelectedDateChanged(object sender, SelectionChangedEventArgs e) { if (IsReady && !_changing) { _from = FromDate.SelectedDate.Value.Date; Refresh(); } } private void ToDate_SelectedDateChanged(object sender, SelectionChangedEventArgs e) { if (IsReady && !_changing) { _to = ToDate.SelectedDate.Value.Date; Refresh(); } } private void Search_KeyUp(object sender, KeyEventArgs e) { if (string.IsNullOrWhiteSpace(Search.Text) || e.Key == Key.Return) { _search = Search.Text; Refresh(); } } private void Export_Click(object sender, RoutedEventArgs e) { var cat = Category.SelectedValue as string; //KeyValuePair cat = (KeyValuePair)Category.SelectedItem; var form = (KeyValuePair)Form.SelectedItem; var formname = Regex.Replace(form.Value, "[^ a-zA-Z0-9]", string.Empty); var filename = string.Format("{0} - {1} - {2:yyyy-MM-dd} - {3:yyyy-MM-dd}.xlsx", cat, formname, FromDate.SelectedDate, ToDate.SelectedDate); var options = new ExcelExportingOptions(); options.ExcelVersion = ExcelVersion.Excel2013; options.ExportStackedHeaders = true; var excelEngine = dataGrid.ExportToExcel(dataGrid.View, options); var workBook = excelEngine.Excel.Workbooks[0]; var sheet = workBook.Worksheets[0]; sheet.Name = "Summary"; sheet.UsedRange.AutofitRows(); sheet.UsedRange.AutofitColumns(); sheet = workBook.Worksheets.Create("Questions"); sheet.Move(0); var questions = new Client().Query(new Filter(x => x.Form.ID).IsEqualTo(form.Key)); sheet.Range[1, 1].Text = form.Value; sheet.Range[1, 1, 1, 3].Merge(); var i = 1; foreach (var row in questions.Rows) if (!row.Get(x => x.Answer).Equals(QAAnswer.Comment)) { sheet.Range[i + 2, 1].Text = string.Format("{0}.", i); sheet.Range[i + 2, 2].Text = string.Format("{0}", row.Get(x => x.Question)); sheet.Range[i + 2, 3].Text = string.Format("[{0}]", row.Get(x => x.Code)); i++; } sheet.UsedRange.AutofitRows(); sheet.UsedRange.AutofitColumns(); try { workBook.SaveAs(filename); var startInfo = new ProcessStartInfo(filename); startInfo.Verb = "open"; startInfo.UseShellExecute = true; Process.Start(startInfo); } catch { MessageBox.Show(string.Format("Unable to Save/Launch [{0}]!\n\nIs the file already open?", filename)); } } #endregion } }