|
@@ -1,936 +0,0 @@
|
|
|
-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.Core.Reports;
|
|
|
-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;
|
|
|
-using System.ComponentModel;
|
|
|
-using Columns = InABox.Core.Columns;
|
|
|
-
|
|
|
-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;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// Interaction logic for QADashboard.xaml
|
|
|
- /// </summary>
|
|
|
- public partial class QADashboard : UserControl, IPanel<DigitalForm>
|
|
|
- {
|
|
|
- private bool _changing;
|
|
|
-
|
|
|
- private DateTime _from;
|
|
|
-
|
|
|
- private string _search = "";
|
|
|
- private DateTime _to;
|
|
|
-
|
|
|
- private CoreTable allforms;
|
|
|
-
|
|
|
- private readonly Dictionary<string, string> QuestionCodes = new();
|
|
|
-
|
|
|
- public bool IsReady { get; set; }
|
|
|
-
|
|
|
- public event DataModelUpdateEvent? OnUpdateDataModel;
|
|
|
-
|
|
|
- private static readonly Dictionary<Type, List<Tuple<string, string>>> 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("Number"))
|
|
|
- {
|
|
|
- e.Column.Width = 80;
|
|
|
- e.Column.HeaderStyle = Application.Current.Resources["TemplateHeaderStyle"] as Style;
|
|
|
- }
|
|
|
- else if (value.Path.Path.Equals("Location_Timestamp"))
|
|
|
- {
|
|
|
- e.Column = new GridImageColumn();
|
|
|
- e.Column.Width = dataGrid.RowHeight;
|
|
|
- e.Column.HeaderStyle = Application.Current.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 = Application.Current.Resources["TemplateHeaderStyle"] as Style;
|
|
|
- }
|
|
|
- else if (value.Path.Path.Equals("Job No"))
|
|
|
- {
|
|
|
- e.Column.Width = 60;
|
|
|
- e.Column.HeaderStyle = Application.Current.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 = Application.Current.Resources["TemplateHeaderStyle"] as Style;
|
|
|
- }
|
|
|
- else if (value.Path.Path.Equals("Completed"))
|
|
|
- {
|
|
|
- e.Column.Width = 100;
|
|
|
- e.Column.HeaderStyle = Application.Current.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 = Application.Current.Resources["TemplateHeaderStyle"] as Style;
|
|
|
- }
|
|
|
- else if (value.Path.Path.Equals("Processed"))
|
|
|
- {
|
|
|
- e.Column.Width = 100;
|
|
|
- e.Column.HeaderStyle = Application.Current.Resources["TemplateHeaderStyle"] as Style;
|
|
|
- }
|
|
|
- else if (value.Path.Path.Equals("Created By"))
|
|
|
- {
|
|
|
- e.Column.Width = 100;
|
|
|
- e.Column.HeaderStyle = Application.Current.Resources["TemplateHeaderStyle"] as Style;
|
|
|
- }
|
|
|
- else if (value.Path.Path.Equals("Created"))
|
|
|
- {
|
|
|
- e.Column.Width = 100;
|
|
|
- e.Column.HeaderStyle = Application.Current.Resources["TemplateHeaderStyle"] as Style;
|
|
|
- (e.Column as GridDateTimeColumn).Pattern = DateTimePattern.CustomPattern;
|
|
|
- (e.Column as GridDateTimeColumn).CustomPattern = "dd MMM yy hh:mm";
|
|
|
- }
|
|
|
- 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 = Application.Current.Resources["TemplateHeaderStyle"] as Style;
|
|
|
- e.Column.HeaderText = QuestionCodes[e.Column.MappingName];
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- #endregion
|
|
|
-
|
|
|
- private Entity? GetEntityForm<T>(Guid id) where T : Entity, IDigitalFormInstance, IRemotable, IPersistent, new()
|
|
|
- {
|
|
|
- var columns = DynamicFormEditWindow.FormColumns<T>();
|
|
|
-
|
|
|
- return new Client<T>().Query(
|
|
|
- new Filter<T>(x => x.ID).IsEqualTo(id),
|
|
|
- columns).Rows.FirstOrDefault()?.ToObject<T>();
|
|
|
- }
|
|
|
-
|
|
|
- private void SaveEntityForm<T>(T entityForm) where T : Entity, IDigitalFormInstance, IRemotable, IPersistent, new()
|
|
|
- {
|
|
|
- new Client<T>().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;
|
|
|
-
|
|
|
- IDigitalFormInstance? entityForm = null;
|
|
|
- Progress.ShowModal("Loading Form", (s) =>
|
|
|
- {
|
|
|
- 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<DigitalFormVariable>(
|
|
|
- new Filter<DigitalFormVariable>(x => x.Form.ID).IsEqualTo(formid),
|
|
|
- null,
|
|
|
- null
|
|
|
- ),
|
|
|
- typeof(DigitalFormVariable)
|
|
|
- );
|
|
|
-
|
|
|
- query.Add(
|
|
|
- new QueryDef<DigitalFormLayout>(
|
|
|
- new Filter<DigitalFormLayout>(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<DigitalFormVariable>());
|
|
|
- var layout = query.Get(typeof(DigitalFormLayout)).Rows.FirstOrDefault()?.ToObject<DigitalFormLayout>();
|
|
|
-
|
|
|
- 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<Dictionary<string, object>>(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<DigitalForm>(
|
|
|
- new Filter<DigitalForm>(x => x.Active).IsEqualTo(true),
|
|
|
- null,
|
|
|
- null
|
|
|
- ),
|
|
|
- typeof(DigitalForm)
|
|
|
- );
|
|
|
- query.Add(
|
|
|
- new QueryDef<Job>(
|
|
|
- LookupFactory.DefineFilter<Job>(),
|
|
|
- new Columns<Job>(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<Job, Guid>(x => x.ID, Guid.Empty);
|
|
|
- alljobs.Set<Job, string>(x => x.JobNumber, "ALL");
|
|
|
- alljobs.Set<Job, string>(x => x.Name, "All Jobs");
|
|
|
- jobs.Rows.Insert(0, alljobs);
|
|
|
- Jobs.ItemsSource = jobs.ToDictionary(x => x.ID, new Expression<Func<Job, object>>[] { x => x.JobNumber, x => x.Name }, x => x.JobNumber);
|
|
|
-
|
|
|
- //Dictionary<Guid, String> joblist = new Dictionary<Guid, string>() { { Guid.Empty, "All Jobs" } };
|
|
|
- //CoreTable jobs = new Client<Job>().Query(
|
|
|
- // LookupFactory.DefineFilter<Job>(),
|
|
|
- // LookupFactory.DefineColumns<Job>(),
|
|
|
- // LookupFactory.DefineSort<Job>()
|
|
|
- //);
|
|
|
- //foreach (var row in jobs.Rows)
|
|
|
- //{
|
|
|
- // //if (row.Get<Employee, String>(x => x.Group.Description).Equals("FACTORY"))
|
|
|
- // joblist[row.Get<Job, Guid>(x => x.ID)] = String.Format("{0} - {1}", row.Get<Job, String>(x => x.JobNumber), row.Get<Job, String>(x => x.Name));
|
|
|
- //}
|
|
|
- //Jobs.ItemsSource = joblist;
|
|
|
- }
|
|
|
-
|
|
|
- public void Shutdown(CancelEventArgs? cancel)
|
|
|
- {
|
|
|
- }
|
|
|
-
|
|
|
- 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<Guid, object>());
|
|
|
- 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<Guid, string>)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<QAQuestion>(
|
|
|
- new Filter<QAQuestion>(x => x.Form.ID).IsEqualTo(form.Key),
|
|
|
- null,
|
|
|
- null
|
|
|
- ),
|
|
|
- typeof(QAQuestion)
|
|
|
- );
|
|
|
- query.Add(
|
|
|
- new QueryDef<DigitalFormVariable>(
|
|
|
- new Filter<DigitalFormVariable>(x => x.Form.ID).IsEqualTo(form.Key),
|
|
|
- null,
|
|
|
- new SortOrder<DigitalFormVariable>(x => x.Sequence)
|
|
|
- ),
|
|
|
- typeof(DigitalFormVariable)
|
|
|
- );
|
|
|
-
|
|
|
- var columns = LookupFactory.DefineColumns(type);
|
|
|
- var sort = LookupFactory.DefineSort(type);
|
|
|
-
|
|
|
- var JobLink = GetJobLink("", type);
|
|
|
-
|
|
|
- var filter = Filter.Create(type, "FormCompleted").IsGreaterThanOrEqualTo(_from)
|
|
|
- .And("FormCompleted").IsLessThan(_to.AddDays(1))
|
|
|
- .And("FormCancelled").IsEqualTo(DateTime.MinValue)
|
|
|
- .And("Form.ID").IsEqualTo(form.Key);
|
|
|
-
|
|
|
- if (jobid != Guid.Empty)
|
|
|
- filter = filter.And($"{JobLink}.ID").IsEqualTo(jobid);
|
|
|
-
|
|
|
- var cols = Columns.Create(type)
|
|
|
- .Add("ID")
|
|
|
- .Add("Number")
|
|
|
- .Add("CreatedBy")
|
|
|
- .Add("Created")
|
|
|
- .Add("Form.ID")
|
|
|
- .Add("FormData")
|
|
|
- .Add("FormCompleted")
|
|
|
- .Add("FormCompletedBy.UserID")
|
|
|
- .Add("Location.Timestamp")
|
|
|
- .Add("Location.Latitude")
|
|
|
- .Add("Location.Longitude");
|
|
|
-
|
|
|
- if(isEntityForm)
|
|
|
- cols.Add("FormProcessed");
|
|
|
-
|
|
|
- if (!string.IsNullOrWhiteSpace(JobLink))
|
|
|
- cols.Add(JobLink + ".JobNumber");
|
|
|
-
|
|
|
- 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);
|
|
|
- }
|
|
|
-
|
|
|
- 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<JobITP>(x => x.ID).InQuery(filter as Filter<JobITPForm>, x => x.Parent.ID),
|
|
|
- new Columns<JobITP>(x => x.ID, x => x.Job.JobNumber));
|
|
|
- }
|
|
|
-
|
|
|
- query.Query();
|
|
|
-
|
|
|
-
|
|
|
- var questions =
|
|
|
- query.Get(typeof(QAQuestion)); // new Client<QAQuestion>().Query(new Filter<QAQuestion>(x => x.QAForm.ID).IsEqualTo(form.Key));
|
|
|
- var variables = query.Get(typeof(DigitalFormVariable)).Rows.Select(x => x.ToObject<DigitalFormVariable>()).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));
|
|
|
- data.Columns.Add("Number", 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("Created", typeof(DateTime));
|
|
|
- data.Columns.Add("Created By", 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<QAQuestion>()), new Dictionary<Guid, object>());
|
|
|
- qaGrid.CollapseMargins();
|
|
|
-
|
|
|
- var i = 1;
|
|
|
- foreach (var row in questions.Rows)
|
|
|
- {
|
|
|
- var id = row.Get<QAQuestion, Guid>(x => x.ID).ToString();
|
|
|
- if (!row.Get<QAQuestion, QAAnswer>(x => x.Answer).Equals(QAAnswer.Comment))
|
|
|
- {
|
|
|
- data.Columns.Add(id, typeof(string));
|
|
|
- var code = row.Get<QAQuestion, string>(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"];
|
|
|
- datarow["Number"] = (string)row["Number"];
|
|
|
-
|
|
|
- var desc = new List<string>();
|
|
|
- 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["Created By"] = (string)row["CreatedBy"];
|
|
|
- datarow["Created"] = (DateTime)row["Created"];
|
|
|
- datarow["Completed"] = (DateTime)row["FormCompleted"];
|
|
|
- datarow["Completed By"] = (string)row["FormCompletedBy.UserID"];
|
|
|
-
|
|
|
- if (isEntityForm)
|
|
|
- datarow["Processed"] = ((DateTime?)row["FormProcessed"] ?? DateTime.MinValue) > DateTime.MinValue;
|
|
|
-
|
|
|
- if(parentType == typeof(JobITP))
|
|
|
- {
|
|
|
- var jobITP = query.Get<JobITP>().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<Dictionary<string, object?>>(qadata);
|
|
|
- if (dict is not null)
|
|
|
- {
|
|
|
- var storage = new DFLoadStorage(dict, null);
|
|
|
- foreach(var variable in variables)
|
|
|
- {
|
|
|
- var value = variable.Deserialize(storage.GetEntry(variable.Code));
|
|
|
- var format = variable.FormatValue(value);
|
|
|
- var sKey = variable.Code.Replace("/", " ");
|
|
|
- if (data.Columns.Contains(sKey))
|
|
|
- {
|
|
|
- datarow[sKey] = format;
|
|
|
- bHasData = true;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- var dict = Serialization.Deserialize<Dictionary<Guid, object>>(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<Guid, string>)Form.SelectedItem;
|
|
|
- if (Category.SelectedValue != null && form.Key != Guid.Empty)
|
|
|
- {
|
|
|
- return form.Key.ToString();
|
|
|
- }
|
|
|
- return "Digital Forms";
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- public DataModel DataModel(Selection selection)
|
|
|
- {
|
|
|
- if ((Form.SelectedItem == null) || (String.IsNullOrWhiteSpace(Category.SelectedValue as String)))
|
|
|
- return new AutoDataModel<DigitalForm>(new Filter<DigitalForm>().None());
|
|
|
-
|
|
|
- Type formtype = CategoryToType(Category.SelectedValue as String);
|
|
|
-
|
|
|
- var form = (KeyValuePair<Guid, string>)Form.SelectedItem;
|
|
|
- if (formtype != null && (form.Key != Guid.Empty))
|
|
|
- {
|
|
|
-
|
|
|
- IFilter filter;
|
|
|
- switch (selection)
|
|
|
- {
|
|
|
- case Selection.Selected:
|
|
|
- var formids = dataGrid.SelectedItems.Select(x => (Guid)(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<DigitalForm>(new Filter<DigitalForm>().None());
|
|
|
- }
|
|
|
-
|
|
|
- public Dictionary<string, object[]> Selected()
|
|
|
- {
|
|
|
- return new Dictionary<string, object[]>();
|
|
|
- }
|
|
|
-
|
|
|
- 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, string> { { Guid.Empty, "" } };
|
|
|
-
|
|
|
- if (!string.IsNullOrWhiteSpace(category))
|
|
|
- {
|
|
|
- forms[Guid.Empty] = "Select Form";
|
|
|
- var rows = allforms.Rows.Where(r => string.Equals(r.Get<DigitalForm, string>(c => c.AppliesTo), category));
|
|
|
- foreach (var row in rows)
|
|
|
- forms[row.Get<DigitalForm, Guid>(x => x.ID)] = row.Get<DigitalForm, string>(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<Type, String> cat = (KeyValuePair<Type, String>)Category.SelectedItem;
|
|
|
- var form = (KeyValuePair<Guid, string>)Form.SelectedItem;
|
|
|
- var formname = Regex.Replace(form.Value, "[^ a-zA-Z0-9]", "");
|
|
|
- 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<QAQuestion>().Query(new Filter<QAQuestion>(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<QAQuestion, QAAnswer>(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<QAQuestion, string>(x => x.Question));
|
|
|
- sheet.Range[i + 2, 3].Text = string.Format("[{0}]", row.Get<QAQuestion, string>(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
|
|
|
-
|
|
|
- }
|
|
|
-}
|