| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326 | using System;using System.Collections.Generic;using System.Diagnostics.CodeAnalysis;using System.Linq;using System.Reflection;using System.Windows;using InABox.Clients;using InABox.Core;namespace InABox.DynamicGrid{    /// <summary>    ///     Interaction logic for FormDesigner.xaml    /// </summary>    public partial class DynamicFormEditWindow : DynamicFormWindow    {        public enum FormResult        {            None,            Cancel,            Save,            Complete        }        public DynamicFormEditWindow()        {            InitializeComponent();            Grid.OnChanged += Grid_OnChanged;            //Complete.IsEnabled = Security.IsAllowed<CanChangeDigitalFormCompletion>();        }        protected override DynamicFormDesignGrid Grid { get => Preview; }        public FormMode Mode        {            get => Grid.Mode;            private set => Grid.Mode = value;        }        public FormResult Result = FormResult.None;        public IDigitalFormDataModel? DataModel        {            get => Grid.DataModel;            set            {                Grid.DataModel = value;                RefreshEnabled();            }        }        /// <summary>        /// Gets or sets the values in the form; can only be accessed after <see cref="DynamicFormDesignGrid.Initialize"/>.        /// </summary>        public Dictionary<string, object?> Values        {            get => Grid.SaveValues();            set            {                Grid.LoadValues(value);                RefreshEnabled();            }        }        private bool IsReopening = false;        private bool HasChanged = false;        private bool HasUnsavedChanges => Grid.IsChanged || HasChanged || DataModel!.Instance.ID == Guid.Empty;        private void RefreshEnabled()        {            var formInstance = DataModel!.Instance;            var completed = formInstance.FormCompleted;            CompletedDate.Content = !completed.IsEmpty() ? $"Completed {completed:d MMM yyyy} at {completed:hh:mm tt}" : "Not completed yet";            if (completed.IsEmpty()                && DFUtils.CanEditForm(formInstance.GetType(), formInstance, DataModel.Entity))            {                Mode = FormMode.Filling;            }            else            {                Mode = Security.IsAllowed<CanEditCompletedForms>()                    ? FormMode.Editing                    : FormMode.ReadOnly;            }            if (Mode == FormMode.Editing || Mode == FormMode.Filling || Mode == FormMode.Preview)            {                SaveForm.IsEnabled = HasUnsavedChanges;            }            else            {                SaveForm.IsEnabled = false;            }            if (!completed.IsEmpty() && Security.IsAllowed<CanChangeDigitalFormCompletion>())            {                CompleteForm.Content = "Re-open form";                CompleteForm.IsEnabled = true;                IsReopening = true;            }            else            {                CompleteForm.Content = "Complete form";                CompleteForm.IsEnabled = Mode == FormMode.Filling && DataModel?.Instance.FormCompleted == DateTime.MinValue;                IsReopening = false;            }        }        private void Grid_OnChanged(DynamicFormDesignGrid sender, string fieldName)        {            if (Mode == FormMode.Editing || Mode == FormMode.Filling || Mode == FormMode.Preview)            {                SaveForm.IsEnabled = true;            }        }        private void Cancel_Click(object sender, RoutedEventArgs e)        {            Result = FormResult.Cancel;            DialogResult = false;        }        private void Complete()        {            if (!Grid.Validate(out var messages))            {                MessageBox.Show(string.Join('\n', messages));                return;            }            if (MessageBox.Show("Are you sure you want to complete this form?", "Confirm Completion", MessageBoxButton.YesNo) == MessageBoxResult.Yes)            {                Result = FormResult.Complete;                DialogResult = true;            }        }        private void Reopen()        {            HasChanged = true;            DataModel!.Instance.FormCompleted = DateTime.MinValue;            DataModel!.Instance.FormCompletedBy.Clear();            RefreshEnabled();        }        private void CompleteForm_Click(object sender, RoutedEventArgs e)        {            if (IsReopening)                Reopen();            else                Complete();        }        private void SaveForm_Click(object sender, RoutedEventArgs e)        {            if (DataModel?.Instance.FormCompleted.IsEmpty() == false && !Grid.Validate(out var messages))            {                MessageBox.Show(string.Join('\n', messages));                return;            }            if (MessageBox.Show("Are you sure you want to save this form?", "Confirm Save", MessageBoxButton.YesNo) == MessageBoxResult.Yes)            {                Result = FormResult.Save;                DialogResult = true;            }        }        public static Columns<TForm> FormColumns<TForm>() where TForm : IDigitalFormInstance        {            return (FormColumns(typeof(TForm)) as Columns<TForm>)!;        }        public static IColumns FormColumns(Type TForm)        {            return Columns.Create<IDigitalFormInstance>(TForm)                .Add<IDigitalFormInstance>(x => x.ID)                .Add<IDigitalFormInstance>(x => x.FormCompleted)                .Add<IDigitalFormInstance>(x => x.FormData)                .Add<IDigitalFormInstance>(x => x.BlobData)                .Add<IDigitalFormInstance>(x => x.Form.ID)                .Add<IDigitalFormInstance>(x => x.Form.Description)                .Add("Parent.ID");        }        public static bool EditDigitalForm(            IDigitalFormInstance formInstance,            [NotNullWhen(true)] out IDigitalFormDataModel? dataModel,            Entity? parent = null)        {            dataModel = null;            var formid = formInstance.Form.ID;            var values = DigitalForm.DeserializeFormData(formInstance);            var results = Client.QueryMultiple(                new KeyedQueryDef<DigitalFormVariable>(new Filter<DigitalFormVariable>(x => x.Form.ID).IsEqualTo(formid)),                new KeyedQueryDef<DigitalFormLayout>(                    new Filter<DigitalFormLayout>(x => x.Form.ID).IsEqualTo(formid)                        .And(x => x.Active).IsEqualTo(true)                        .And(x => x.Layout).IsNotEqualTo("")));            var variables = results[nameof(DigitalFormVariable)].Rows.Select(x => x.ToObject<DigitalFormVariable>()).ToArray();            var desktopLayout = results[nameof(DigitalFormLayout)]                .Rows.FirstOrDefault(x => x.Get<DigitalFormLayout, DFLayoutType>(x => x.Type) == DFLayoutType.Desktop)                ?.ToObject<DigitalFormLayout>();            var layout = desktopLayout ?? results[nameof(DigitalFormLayout)].ToObjects<DigitalFormLayout>().FirstOrDefault();            if (layout == null)            {                MessageBox.Show("No layout found form form!");                return false;            }            if (parent is null)            {                var parentlink = CoreUtils.HasProperty(formInstance.GetType(), "Parent") ? CoreUtils.GetPropertyValue(formInstance, "Parent") as IEntityLink : null;                var parenttype = parentlink?.GetType().BaseType?.GetGenericArguments().FirstOrDefault();                if (parenttype != null && parentlink != null)                {                    var parentid = parentlink.ID;                    var filter = Filter.Create(parenttype);                    filter.Expression = CoreUtils.GetMemberExpression(parenttype, "ID");                    filter.Operator = Operator.IsEqualTo;                    filter.Value = parentid;                    var client = (Activator.CreateInstance(typeof(Client<>).MakeGenericType(parenttype)) as Client)!;                    parent = client.Query(filter, null, null).Rows.FirstOrDefault()?.ToObject(parenttype) as Entity;                }                if (parent == null)                {                    Logger.Send(LogType.Error, "", $"Form parent is null; Form Type: {formInstance.GetType()}; Parent Type: {parenttype}; Form ID: {formInstance.ID}");                    MessageBox.Show("An error occurred while loading the form: Form Entity is null");                    return false;                }            }            var form = new DynamicFormEditWindow            {                Type = layout.Type,                Title = string.Format("Viewing {0}", formInstance.Form.Description)                //Completed = !formInstance.FormCompleted.IsEmpty()            };            form.LoadLayout(layout, variables);            try            {                dataModel = formInstance.CreateDataModel(parent);                dataModel.OnModelSaved += (model) =>                {                    DFUtils.OnSave(formInstance.GetType(), formInstance, parent);                };                form.DataModel = dataModel;            }            catch (Exception e)            {                Logger.Send(LogType.Error, ClientFactory.UserID, $"Error during Edit Form / CreateDataModel: {CoreUtils.FormatException(e)}");            }            form.Initialize();            if (values is not null)                form.Values = values;            if (form.ShowDialog() == true)            {                if (form.Result == FormResult.Complete)                {                    formInstance.FormCompleted = DateTime.Now;                    formInstance.FormCompletedBy.ID = ClientFactory.UserGuid;                    formInstance.FormCompletedBy.UserID = ClientFactory.UserID;                    /*formInstance.FormCompleted = form.Completed                        ? formInstance.FormCompleted.IsEmpty()                            ? DateTime.Now                            : formInstance.FormCompleted                        : DateTime.MinValue;                    formInstance.FormCompletedBy.ID = form.Completed                        ? !formInstance.FormCompletedBy.IsValid()                            ? ClientFactory.UserGuid                            : formInstance.FormCompletedBy.ID                        : Guid.Empty;                    formInstance.FormCompletedBy.UserID = form.Completed                        ? string.IsNullOrWhiteSpace(formInstance.FormCompletedBy.UserID)                            ? ClientFactory.UserID                            : formInstance.FormCompletedBy.UserID                        : "";*/                }                DigitalForm.SerializeFormData(formInstance, variables, form.Values);            }            return form.Result == FormResult.Save || form.Result == FormResult.Complete;        }        public static bool EditDigitalForm<TForm>(Guid formID, [NotNullWhen(true)] out IDigitalFormDataModel? dataModel)            where TForm : Entity, IDigitalFormInstance, IRemotable, IPersistent, new()        {            var form = new Client<TForm>()                .Query(                    new Filter<TForm>(x => x.ID).IsEqualTo(formID),                    FormColumns<TForm>())                .Rows.FirstOrDefault()?.ToObject<TForm>();            if(form is null)            {                throw new Exception($"{typeof(TForm)} {formID} does not exist");            }            return EditDigitalForm(form, out dataModel);        }        private void DynamicFormWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e)        {            if(DialogResult != true && HasUnsavedChanges)            {                if(MessageBox.Show("This form has unsaved changes. Do you wish to discard them?", "Discard Changes?", MessageBoxButton.YesNo) != MessageBoxResult.Yes)                {                    e.Cancel = true;                }            }        }    }}
 |