| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674 | using System;using System.Collections.Generic;using System.Globalization;using System.IO;using System.Linq;using System.Text;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() => new Document            {                FileName = FileName,                Data = Data,                TimeStamp = DateTime.Now,                ID = ID            };        }    }    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,            Action<CoreTable?, Exception?> action)        {            if (!_showall)                criteria.Add(new Filter<DigitalForm>(x => x.Active).IsEqualTo(true));            base.Reload(criteria, columns, ref sort, 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.GetFormEntityType(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!");        }    }}
 |