123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681 |
- using System;
- using System.Collections.Generic;
- using System.Globalization;
- using System.IO;
- using System.Linq;
- using System.Text;
- using System.Threading;
- using System.Windows;
- using System.Windows.Controls;
- using System.Windows.Media.Imaging;
- using FastReport;
- using InABox.Clients;
- using InABox.Core;
- using InABox.Core.Reports;
- using InABox.Scripting;
- using InABox.Wpf;
- using InABox.WPF;
- using Microsoft.Win32;
- using NPOI.HPSF;
- namespace InABox.DynamicGrid
- {
- public class DigitalFormExportData
- {
- public string Code { get; set; }
- public string Description { get; set; }
- public string AppliesTo { get; set; }
- public DigitalFormExportData() { }
- public DigitalFormExportData(DigitalForm form)
- {
- Code = form.Code;
- Description = form.Description;
- AppliesTo = form.AppliesTo;
- }
- public List<LayoutData> Layouts { get; set; }
- public List<VariableData> Variables { get; set; }
- public List<DocumentData> Documents { get; set; }
- public DigitalForm ToForm() => new DigitalForm
- {
- Code = Code,
- Description = Description,
- AppliesTo = AppliesTo
- };
- public class LayoutData
- {
- public string Code { get; set; }
- public string Description { get; set; }
- public DFLayoutType Type { get; set; }
- public string Layout { get; set; }
- public LayoutData() { }
- public LayoutData(DigitalFormLayout layout)
- {
- Code = layout.Code;
- Description = layout.Description;
- Type = layout.Type;
- Layout = layout.Layout;
- }
- public DigitalFormLayout ToLayout() => new DigitalFormLayout
- {
- Code = Code,
- Description = Description,
- Type = Type,
- Layout = Layout
- };
- }
- public class VariableData
- {
- public string Code { get; set; }
- public string Description { get; set; }
- public string VariableType { get; set; }
- public string Parameters { get; set; }
- public bool Required { get; set; }
- public bool Secure { get; set; }
- public bool Retain { get; set; }
- public bool Hidden { get; set; }
- public long Sequence { get; set; }
- public VariableData() { }
- public VariableData(DigitalFormVariable variable)
- {
- Code = variable.Code;
- Description = variable.Description;
- VariableType = variable.VariableType;
- Parameters = variable.Parameters;
- Required = variable.Required;
- Secure = variable.Secure;
- Retain = variable.Retain;
- Hidden = variable.Hidden;
- Sequence = variable.Sequence;
- }
- public DigitalFormVariable ToVariable() => new DigitalFormVariable
- {
- Code = Code,
- Description = Description,
- VariableType = VariableType,
- Parameters = Parameters,
- Required = Required,
- Secure = Secure,
- Retain = Retain,
- Hidden = Hidden,
- Sequence = Sequence
- };
- }
- public class DocumentData
- {
- public string FileName { get; set; }
- public byte[] Data { get; set; }
- public Guid ID { get; set; }
- public DocumentData() { }
- public DocumentData(Document document)
- {
- FileName = document.FileName;
- Data = document.Data;
- ID = document.ID;
- }
- public Document ToDocument()
- {
- var doc = new Document()
- {
- ID = ID
- };
- doc.CommitChanges();
- doc.FileName = FileName;
- doc.Data = Data;
- doc.TimeStamp = DateTime.Now;
- return doc;
- }
- }
- }
- public class DigitalFormGrid : DynamicDataGrid<DigitalForm>
- {
- private bool _showall;
- private Button CopyForm = null!; // Late-initialised
- protected override void Init()
- {
- base.Init();
- AddButton("Show All", null, ShowAllClick);
- // TODO: Add back in
- //ActionColumns.Add(new DynamicImageColumn(ReportImage, ReportClick));
- AddButton("Groups", null, EditGroupsClick);
- CopyForm = AddButton("Duplicate", InABox.Wpf.Resources.copy.AsBitmapImage(), CopyForm_Click);
- CopyForm.IsEnabled = false;
- if (!Security.CanEdit<DigitalForm>())
- {
- CopyForm.Visibility = Visibility.Collapsed;
- }
- OnCustomiseEditor += DigitalFormGrid_OnCustomiseEditor;
- }
- protected override void DoReconfigure(DynamicGridOptions options)
- {
- base.DoReconfigure(options);
- options.ImportData = true;
- options.ExportData = true;
- options.FilterRows = true;
- options.SelectColumns = true;
- }
- protected override void SelectItems(CoreRow[]? rows)
- {
- base.SelectItems(rows);
- CopyForm.IsEnabled = rows is not null && rows.Length == 1;
- }
- private bool CopyForm_Click(Button btn, CoreRow[] rows)
- {
- if(rows.Length != 1)
- {
- MessageWindow.ShowMessage("Please select one form to copy.", "Invalid selection.");
- return false;
- }
- var form = rows[0].ToObject<DigitalForm>();
- Client.EnsureColumns(form,
- Columns.None<DigitalForm>().Add(x => x.Description)
- .Add(x => x.AppliesTo)
- .Add(x => x.Secure)
- .Add(x => x.Final)
- .Add(x => x.Group.ID));
- var newForm = new DigitalForm();
- newForm.Description = form.Description;
- newForm.AppliesTo = form.AppliesTo;
- newForm.Secure = form.Secure;
- newForm.Final = form.Final;
- newForm.Group.ID = form.Group.ID;
- var children = Client.QueryMultiple(
- new KeyedQueryDef<DigitalFormLayout>(
- new Filter<DigitalFormLayout>(x => x.Form.ID).IsEqualTo(form.ID),
- Columns.None<DigitalFormLayout>().Add(x => x.Code)
- .Add(x => x.Description)
- .Add(x => x.Type)
- .Add(x => x.Layout)
- .Add(x => x.Active)),
- new KeyedQueryDef<DigitalFormVariable>(
- new Filter<DigitalFormVariable>(x => x.Form.ID).IsEqualTo(form.ID),
- Columns.None<DigitalFormVariable>().Add(x => x.Code)
- .Add(x => x.Description)
- .Add(x => x.VariableType)
- .Add(x => x.Group)
- .Add(x => x.Parameters)
- .Add(x => x.Required)
- .Add(x => x.Secure)
- .Add(x => x.Retain)
- .Add(x => x.Hidden)
- .Add(x => x.Sequence)),
- new KeyedQueryDef<ReportTemplate>(
- new Filter<ReportTemplate>(x => x.Section).IsEqualTo(form.ID.ToString()),
- Columns.None<ReportTemplate>().Add(x => x.Section)
- .Add(x=>x.Name)
- .Add(x=>x.Script)
- .Add(x=>x.Visible)
- .Add(x=>x.AllRecords)
- .Add(x=>x.DataModel)
- .Add(x=>x.PrinterName)
- .Add(x=>x.SelectedRecords)
- .Add(x=>x.RDL)
- .Add(x=>x.Section)),
- new KeyedQueryDef<DigitalFormDocument>(
- new Filter<DigitalFormDocument>(x => x.EntityLink.ID).IsEqualTo(form.ID),
- Columns.None<DigitalFormDocument>().Add(x => x.Type)
- .Add(x => x.DocumentLink.ID)
- .Add(x => x.Superceded)
- .Add(x => x.Thumbnail)
- .Add(x => x.Notes)));
- if (EditItems(new[] { newForm }, type =>
- {
- return children.GetOrDefault(type.Name);
- }))
- {
- return true;
- }
- else
- {
- return false;
- }
- }
- private bool EditGroupsClick(Button arg1, CoreRow[] arg2)
- {
- new MasterList(typeof(DigitalFormGroup)).ShowDialog();
- return false;
- }
- private BitmapImage? ReportImage(CoreRow arg)
- {
- return arg != null ? Wpf.Resources.printer.AsBitmapImage() : null;
- }
- /*private bool ReportClick(CoreRow arg)
- {
- if (arg == null)
- return false;
- var typename = arg.Get<DigitalForm, string>(c => c.AppliesTo);
- var formid = arg.Get<DigitalForm, Guid>(c => c.ID);
- // Get Applies To
- /*Type type = CoreUtils.GetEntity("Comal.Classes."+typename);
- CoreTable entity = new CoreTable();
- entity.LoadColumns(type);
-
- // Get Form Details
- CoreTable form = new CoreTable();
- form.Columns.Add(new CoreColumn() { ColumnName = "ID", DataType = typeof(Guid) });
- form.Columns.Add(new CoreColumn() { ColumnName = "Parent.ID", DataType = typeof(Guid) });
- form.Columns.Add(new CoreColumn() { ColumnName = CoreUtils.GetFullPropertyName<IDigitalFormInstance, String>(x => x.Form.Description, "."), DataType = typeof(String) });
- form.Columns.Add(new CoreColumn() { ColumnName = CoreUtils.GetFullPropertyName<IDigitalFormInstance, String>(x => x.FormCompletedBy.UserID, "."), DataType = typeof(String) });
- form.Columns.Add(new CoreColumn() { ColumnName = CoreUtils.GetFullPropertyName<IDigitalFormInstance, DateTime>(x => x.FormCompleted, "."), DataType = typeof(String) });
- form.Columns.Add(new CoreColumn() { ColumnName = CoreUtils.GetFullPropertyName<IDigitalFormInstance, String>(x => x.Location.Address, "."), DataType = typeof(String) });
- form.Columns.Add(new CoreColumn() { ColumnName = CoreUtils.GetFullPropertyName<IDigitalFormInstance, double>(x => x.Location.Latitude, "."), DataType = typeof(String) });
- form.Columns.Add(new CoreColumn() { ColumnName = CoreUtils.GetFullPropertyName<IDigitalFormInstance, double>(x => x.Location.Longitude, "."), DataType = typeof(String) });
-
- var variables = new Client<DigitalFormVariable>().Query(new Filter<DigitalFormVariable>(x => x.Form.ID).IsEqualTo(formid));
- foreach (var row in variables.Rows)
- {
- form.Columns.Add(
- new CoreColumn()
- {
- ColumnName = row.Get<DigitalFormVariable, String>(c => c.Code),
- DataType = DigitalFormVariable.DataType(row.Get<DigitalFormVariable, DigitalFormVariableType>(c => c.VariableType))
- }
- );
- }*
- // Create DataModel
- //DigitalFormReportDataModel model = new DigitalFormReportDataModel(form,entity,typename);
- AutoDataModel<DigitalForm> model = new AutoDataModel<DigitalForm>(new Filter<DigitalForm>(x => x.ID).IsEqualTo(formid));
- // Load Template
- var template = new Client<ReportTemplate>()
- .Load(new Filter<ReportTemplate>(x => x.Section).IsEqualTo("DigitalForms").And(x => x.Name).IsEqualTo(formid.ToString()))
- .FirstOrDefault();
- if (template == null)
- {
- template = new ReportTemplate
- {
- Section = "DigitalForms",
- Name = formid.ToString(),
- Visible = false
- };
- new Client<ReportTemplate>().Save(template, "");
- }
- ReportUtils.DesignReport(template, model);
- // Preview Report
- return false;
- }*/
- private bool ShowAllClick(Button arg1, CoreRow[] arg2)
- {
- _showall = !_showall;
- UpdateButton(arg1, null, _showall ? "Hide Inactive" : "Show All");
- return true;
- }
- protected override void Reload(
- Filters<DigitalForm> criteria, Columns<DigitalForm> columns, ref SortOrder<DigitalForm>? sort,
- CancellationToken token, Action<CoreTable?, Exception?> action)
- {
- if (!_showall)
- criteria.Add(new Filter<DigitalForm>(x => x.Active).IsEqualTo(true));
- base.Reload(criteria, columns, ref sort, token, action);
- }
- public override DynamicEditorPages LoadEditorPages(DigitalForm item)
- {
- var pages = base.LoadEditorPages(item);
- pages.Add(new DigitalFormReportGrid());
- return pages;
- }
- private DynamicVariableGrid? GetVariableGrid(IDynamicEditorForm sender)
- => sender.Pages?.FirstOrDefault(x => x is DynamicVariableGrid)
- as DynamicVariableGrid;
- private List<DigitalFormVariable> GetVariables(IDynamicEditorForm sender)
- => GetVariableGrid(sender)?.Items.ToList() ?? new List<DigitalFormVariable>();
- // Using the event because it also has the editor form 'sender'.
- private void DigitalFormGrid_OnCustomiseEditor(IDynamicEditorForm sender, DigitalForm[]? items, DynamicGridColumn column, BaseEditor editor)
- {
- if(editor is ExpressionEditor exp && ( new Column<DigitalForm>(x => x.DescriptionExpression).IsEqualTo(column.ColumnName) || new Column<DigitalForm>(x => x.ExportExpression).IsEqualTo(column.ColumnName)))
- {
- exp.OnGetVariables += () =>
- {
- var variables = new List<string>();
- foreach (var variable in GetVariables(sender))
- {
- foreach (var col in variable.GetVariableColumns())
- variables.Add($"Data.{col.ColumnName}");
- }
- var appliesTo = items?.Select(x => x.AppliesTo).Distinct().SingleOrDefault();
- if (!appliesTo.IsNullOrWhiteSpace() && DFUtils.GetFormInstanceType(appliesTo) is Type instanceType)
- {
- foreach(var property in DatabaseSchema.Properties(instanceType).Where(x => !x.Name.StartsWith("Parent.")))
- variables.Add($"Form.{property.Name}");
- }
-
- if (!appliesTo.IsNullOrWhiteSpace() && DFUtils.FormEntityType(appliesTo) is Type entityType)
- {
- foreach(var property in DatabaseSchema.Properties(entityType))
- variables.Add($"{entityType.EntityName().Split('.').Last()}.{property.Name}");
- }
- variables.Sort();
- return variables;
- };
- }
- }
- public override bool EditItems(DigitalForm[] items, Func<Type, CoreTable?>? PageDataHandler = null, bool PreloadPages = false)
- {
- // Need to do this to make sure that the variables are available to the layouts (and vice versa?)
- return base.EditItems(items, PageDataHandler, true);
- }
- private const string ExportFileFilter = "Excel Files (*.xls, *xlsx)|*.xls;*.xlsx|Digital Forms (*.prs-form)|*.prs-form";
- protected override void DoImport()
- {
- var dialog = new OpenFileDialog
- {
- Filter = ExportFileFilter
- };
- if (dialog.ShowDialog() != true)
- return;
- String extension = Path.GetExtension(dialog.FileName) ?? "";
- if (extension.ToLower().Equals(".xls") || extension.ToLower().Equals(".xlsx"))
- {
-
- String appliesto = "";
- String code = "";
- var lookups = new DigitalFormCategoryLookups(null).Lookups();
- if (!DictionaryEdit.Execute<String>(lookups, ref appliesto, "Applies To", "Select Form Type") || String.IsNullOrWhiteSpace(appliesto))
- return;
- Progress.ShowModal("Creating Form", (progress) =>
- {
- var codes = new Client<DigitalForm>().Query(
- null,
- Columns.None<DigitalForm>().Add(x => x.Code),
- null
- ).Rows.Select(r => r.Get<DigitalForm, String>(c => c.Code)).ToArray();
- int i = 1;
- code = Path.GetFileNameWithoutExtension(dialog.FileName).ToUpper();
- while (codes.Contains(code))
- code = $"{Path.GetFileNameWithoutExtension(dialog.FileName).ToUpper()} ({i++})";
-
- DigitalForm form = new DigitalForm();
- form.Code = code;
- form.Description = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(Path.GetFileNameWithoutExtension(dialog.FileName));
- form.AppliesTo = appliesto;
- new Client<DigitalForm>().Save(form, $"Imported from {dialog.FileName}");
- progress.Report("Importing Data");
- DFLayout data;
- var variables = new List<DigitalFormVariable>();
-
- var layout = new DigitalFormLayout();
- layout.Form.ID = form.ID;
- layout.Code = form.Code;
- layout.Description = form.Description;
- using (var fs = new FileStream(dialog.FileName, FileMode.Open, FileAccess.Read, FileShare.Read))
- {
- var spreadsheet = new Spreadsheet(fs);
- data = DigitalFormUtils.LoadLayout(spreadsheet);
- layout.Layout = data.SaveLayout();
- }
- new Client<DigitalFormLayout>().Save(layout, $"Imported from {dialog.FileName}");
- progress.Report("Setting Up Variables");
- String group = "";
- foreach (var element in data.Elements)
- {
- if (element is DFLayoutHeader header)
- {
- group = header.Header;
- }
- else if (element is DFLayoutField field)
- {
- var variable = new DigitalFormVariable();
- variable.Form.ID = form.ID;
- variable.SetFieldType(field.GetType());
- variable.SaveProperties(field.GetProperties());
- variable.Group = group;
- variable.Code = field.Name;
- variable.Description = field.Name;
- variables.Add(variable);
- }
- }
- if (variables.Any())
- new Client<DigitalFormVariable>().Save(variables, $"Imported from {dialog.FileName}");
- progress.Report("Creating Report");
- var model = DigitalFormUtils.GetDataModel(appliesto, variables);
- var template = DigitalFormUtils.GenerateReport(layout, model);
- var report = new ReportTemplate();
- report.Section = form.ID.ToString();
- report.DataModel = model.Name;
- report.Name = form.Description;
- report.RDL = template?.SaveToString();
- new Client<ReportTemplate>().Save(report, $"Imported from {dialog.FileName}");
- });
- MessageBox.Show($"[{code}] imported successully!");
- Refresh(false, true);
- return;
- }
- DigitalFormExportData? data;
- using(var stream = dialog.OpenFile())
- {
- data = Serialization.Deserialize<DigitalFormExportData>(stream);
- if (data is null)
- {
- MessageBox.Show("File corrupt");
- return;
- }
- }
- try
- {
- var form = data.ToForm();
- var layouts = data.Layouts.Select(x => x.ToLayout()).ToList();
- var variables = data.Variables.Select(x => x.ToVariable()).ToList();
- var documents = data.Documents.Select(x => x.ToDocument()).ToList();
- var formDocuments = new List<DigitalFormDocument>();
- foreach (var document in documents)
- {
- new Client<Document>().Save(document, "");
- var digitalFormDocument = new DigitalFormDocument();
- digitalFormDocument.DocumentLink.ID = document.ID;
- digitalFormDocument.DocumentLink.Synchronise(document);
- formDocuments.Add(digitalFormDocument);
- }
- if (EditItems(new DigitalForm[] { form }, (type) =>
- {
- var table = new CoreTable();
- table.LoadColumns(type);
- if(type == typeof(DigitalFormLayout))
- {
- table.LoadRows(layouts);
- }
- else if(type == typeof(DigitalFormVariable))
- {
- table.LoadRows(variables);
- }
- else if(type == typeof(DigitalFormDocument))
- {
- table.LoadRows(formDocuments);
- }
- return table;
- }))
- {
- Refresh(false, true);
- }
- /*new Client<DigitalForm>().Save(form, "Imported by user");
- foreach (var layout in layouts)
- {
- layout.Form.ID = form.ID;
- new Client<DigitalFormLayout>().Save(layout, "");
- }
- foreach (var variable in variables)
- {
- variable.Form.ID = form.ID;
- new Client<DigitalFormVariable>().Save(variable, "");
- }
- foreach (var document in documents)
- {
- new Client<Document>().Save(document, "");
- var digitalFormDocument = new DigitalFormDocument();
- digitalFormDocument.EntityLink.ID = form.ID;
- digitalFormDocument.DocumentLink.ID = document.ID;
- new Client<DigitalFormDocument>().Save(digitalFormDocument, "");
- }*/
- }
- catch(Exception e)
- {
- MessageBox.Show(e.Message);
- }
- }
- protected override void DoExport()
- {
- var rows = SelectedRows;
- if(rows.Length == 0)
- {
- MessageBox.Show("Please select a form to export.");
- return;
- }
- else if(rows.Length > 1)
- {
- MessageBox.Show("Please select only one form to export.");
- return;
- }
- var formID = rows[0].Get<DigitalForm, Guid>(x => x.ID);
- var results = Client.QueryMultiple(
- new KeyedQueryDef<DigitalForm>(
- new Filter<DigitalForm>(x => x.ID).IsEqualTo(formID),
- Columns.None<DigitalForm>().Add(x => x.Code)
- .Add(x => x.Description)
- .Add(x => x.AppliesTo)),
- new KeyedQueryDef<DigitalFormLayout>(
- new Filter<DigitalFormLayout>(x => x.Form.ID).IsEqualTo(formID),
- Columns.None<DigitalFormLayout>().Add(x => x.Code)
- .Add(x => x.Description)
- .Add(x => x.Type)
- .Add(x => x.Layout)),
- new KeyedQueryDef<DigitalFormVariable>(
- new Filter<DigitalFormVariable>(x => x.Form.ID).IsEqualTo(formID),
- Columns.None<DigitalFormVariable>().Add(x => x.Code)
- .Add(x => x.Description)
- .Add(x => x.VariableType)
- .Add(x => x.Parameters)
- .Add(x => x.Required)
- .Add(x => x.Secure)
- .Add(x => x.Retain)
- .Add(x => x.Hidden)
- .Add(x => x.Sequence)),
- new KeyedQueryDef<Document>(
- new Filter<Document>(x => x.ID).InQuery(
- new Filter<DigitalFormDocument>(x => x.EntityLink.ID).IsEqualTo(formID),
- x => x.DocumentLink.ID),
- Columns.None<Document>().Add(x => x.FileName)
- .Add(x => x.Data)));
- var data = new DigitalFormExportData(results.Get<DigitalForm>().Rows.First().ToObject<DigitalForm>())
- {
- Layouts = results.Get<DigitalFormLayout>().ToObjects<DigitalFormLayout>().Select(x => new DigitalFormExportData.LayoutData(x)).ToList(),
- Variables = results.Get<DigitalFormVariable>().ToObjects<DigitalFormVariable>().Select(x => new DigitalFormExportData.VariableData(x)).ToList(),
- Documents = results.Get<Document>().ToObjects<Document>().Select(x => new DigitalFormExportData.DocumentData(x)).ToList()
- };
- var filename = rows[0].Get<DigitalForm, string>(x => x.Description);
- if (string.IsNullOrWhiteSpace(filename))
- filename = rows[0].Get<DigitalForm, string>(x => x.Code);
- if (string.IsNullOrWhiteSpace(filename))
- filename = "form";
- var dialog = new SaveFileDialog
- {
- Filter = ExportFileFilter,
- FileName = $"{filename}.prs-form"
- };
- if(dialog.ShowDialog() == true)
- {
- using var stream = dialog.OpenFile();
- Serialization.Serialize(data, stream);
- }
- }
- protected override void DoValidate(DigitalForm[] items, List<string> errors)
- {
- base.DoValidate(items, errors);
- if (items.Any(x => string.IsNullOrWhiteSpace(x.AppliesTo)))
- errors.Add("[Applies To] must not be blank!");
- }
- }
- }
|