| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385 | using InABox.Clients;using InABox.Core;using InABox.Database;using InABox.DynamicGrid;using InABox.WPF;using Microsoft.CodeAnalysis.CSharp.Syntax;using Newtonsoft.Json.Linq;using NPOI.POIFS.FileSystem;using PRSClasses;using Syncfusion.Data.Extensions;using Syncfusion.DocIO.DLS;using System;using System.Collections.Generic;using System.Drawing;using System.Globalization;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Windows.Interop;using System.Windows.Media.Imaging;using System.Windows.Navigation;namespace PRS.Shared{    public class Update_7_34 : DatabaseUpdateScript    {        public override VersionNumber Version => new VersionNumber(7, 34);        public override bool Update()        {            Logger.Send(LogType.Information, "", "Updating form data");            var fnc = typeof(Update_7_34).GetMethod("UpdateForm", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic)!;            FormUpdater.UpdateAllForms((_, vars) => vars.Count == 0, UpdateForm);            Logger.Send(LogType.Information, "", "Updating form data complete");            return true;        }        private Guid SaveDocument(byte[] data)        {            var id = Guid.NewGuid();            var document = new Document            {                FileName = $"{id}.formdocument",                Data = data            };            DbFactory.Provider.Save(document);            return id;        }        private DFLayoutEmbeddedMediaValue ConvertImage(byte[] data)        {            var thumbnail = ImageUtils.BitmapImageFromBytes(data)?.Resize(200, 200).ToArray<BmpBitmapEncoder>();            return new DFLayoutEmbeddedMediaValue            {                ID = SaveDocument(data),                Thumbnail = thumbnail,                Data = data            };        }        private DFLayoutEmbeddedMediaValue ConvertVideo(byte[] data)        {            var thumbnail = ImageUtils.BitmapImageFromBytes(data)?.Resize(200, 200).ToArray<BmpBitmapEncoder>();            return new DFLayoutEmbeddedMediaValue            {                ID = SaveDocument(data),                Thumbnail = new Bitmap(256, 256).WatermarkImage("Video Data", Color.Gray).AsBitmapImage().ToArray<BmpBitmapEncoder>(),                Data = data            };        }        private DFLayoutLookupValue ConvertLookup(DigitalFormVariable variable, Guid lookupID)        {            if(lookupID == Guid.Empty)            {                return new DFLayoutLookupValue();            }            var properties = (variable.GetProperties() as DFLayoutLookupFieldProperties)!;            if (!CoreUtils.TryGetEntity(properties.LookupType, out var type))            {                Logger.Send(LogType.Error, "", $"Invalid lookup type {properties.LookupType}");                return new DFLayoutLookupValue { ID = lookupID };            }            var client = ClientFactory.CreateClient(type);            var columns = LookupFactory.DefineColumns(type);            foreach (var property in properties.AdditionalPropertiesList)            {                columns.Add(property);            }            var filter = Filter.Create(type, "ID").IsEqualTo(lookupID);            var row = client.Query(                filter,                columns,                LookupFactory.DefineSort(type)            ).Rows.FirstOrDefault();            if (row is null)            {                return new DFLayoutLookupValue { ID = lookupID };            }            var value = new DFLayoutLookupValue            {                ID = lookupID,                Values = row.ToDictionary(new[] { "ID" })            };            value.Text = LookupFactory.FormatLookup(type, value.Values, Enumerable.Empty<string>());            return value;        }        private object? Deserialize(DigitalFormVariable variable, Type fieldType, DFLoadStorage values)        {            var value = values.GetValue(variable.Code);            if (fieldType == typeof(DFLayoutBooleanField))            {                if (value is bool b)                {                    return b;                }                else if (bool.TryParse(value as string, out var result))                {                    return result;                }                else if (value is string str)                {                    var properties = (variable.GetProperties() as DFLayoutBooleanFieldProperties)!;                    if (str == properties.TrueValue)                        return true;                    if (str == properties.FalseValue)                        return false;                    throw new Exception($"Invalid boolean value {str}");                }                return variable.Deserialize(values.GetEntry(variable.Code));            }            else if(fieldType == typeof(DFLayoutDateField))            {                if (value is DateTime date)                    return date;                if (DateTime.TryParseExact(value as string, "dd-MM-yyyy", CultureInfo.InvariantCulture, DateTimeStyles.None, out var result))                    return result;                if (DateTime.TryParse(value as string, out result))                    return result;                return variable.Deserialize(values.GetEntry(variable.Code));            }            else if (fieldType == typeof(DFLayoutDoubleField))            {                if (value is double d)                    return d;                if (double.TryParse(value as string, out var result))                    return result;                if(value is not null)                {                    throw new Exception($"Invalid double '{value}'");                }                return variable.Deserialize(values.GetEntry(variable.Code));            }            else if (fieldType == typeof(DFLayoutEmbeddedImage))            {                if (value is byte[] b)                    return ConvertImage(b);                else if(value is string str)                {                    if (Guid.TryParse(str, out var id))                        return variable.Deserialize(values.GetEntry(variable.Code));                    try                    {                        var tuple = Serialization.Deserialize<Tuple<Guid, byte[]>>(str, true);                        if(tuple != null)                        {                            return new DFLayoutEmbeddedMediaValue                            {                                ID = tuple.Item1,                                Thumbnail = tuple.Item2,                            };                        }                    }                    catch                    {                    }                    try                    {                        return ConvertImage(System.Convert.FromBase64String(str));                    }                    catch(Exception e)                    {                        throw new Exception($"Error in image data; invalid Base-64: {e.Message}");                    }                }                return variable.Deserialize(values.GetEntry(variable.Code));            }            else if (fieldType == typeof(DFLayoutIntegerField))            {                if (value is null)                    return variable.Deserialize(values.GetEntry(variable.Code));                if (value.GetType().IsNumeric())                {                    return System.Convert.ToInt32(value);                }                if (int.TryParse(value as string, out var result))                    return result;                if(value != null)                {                    throw new Exception($"Invalid integer '{value}'");                }                return variable.Deserialize(values.GetEntry(variable.Code));            }            else if(fieldType == typeof(DFLayoutLookupField))            {                if(value is string str && Guid.TryParse(str, out var id))                {                    return ConvertLookup(variable, id);                }                return variable.Deserialize(values.GetEntry(variable.Code));            }            else if(fieldType == typeof(DFLayoutMultiImage))            {                string[]? imgs;                try                {                    imgs = values.GetValue<string[]?>(variable.Code);                }                catch                {                    var data = values.GetValue<byte[]>(variable.Code);                    if(data != null)                    {                        var newValueList = new DFLayoutEmbeddedMediaValues();                        newValueList.Add(ConvertImage(data));                        return newValueList;                    }                    return variable.Deserialize(values.GetEntry(variable.Code));                }                if (imgs is null)                {                    return variable.Deserialize(values.GetEntry(variable.Code));                }                var valueList = new DFLayoutEmbeddedMediaValues();                foreach (string s in imgs)                {                    if (!s.IsNullOrWhiteSpace())                    {                        try                        {                            var externaldata = Serialization.Deserialize<(Guid, byte[])>(s, strict: true);                            if (externaldata.Item1 != Guid.Empty)                            {                                valueList.Add(new DFLayoutEmbeddedMediaValue()                                {                                    ID = externaldata.Item1,                                    Thumbnail = externaldata.Item2                                });                            }                        }                        catch                        {                            try                            {                                var data = System.Convert.FromBase64String(s);                                valueList.Add(ConvertImage(data));                            }                            catch                            {                                throw new Exception($"Could not convert multi-image");                            }                        }                    }                }                return valueList;            }            else if(fieldType == typeof(DFLayoutMultiSignaturePad))            {                return variable.Deserialize(values.GetEntry(variable.Code));            }            else if(fieldType == typeof(DFLayoutOptionField))            {                return variable.Deserialize(values.GetEntry(variable.Code));            }            else if (fieldType == typeof(DFLayoutSignaturePad))            {                return variable.Deserialize(values.GetEntry(variable.Code));            }            else if (fieldType == typeof(DFLayoutStringField))            {                return variable.Deserialize(values.GetEntry(variable.Code));            }            else if (fieldType == typeof(DFLayoutTimeField))            {                if (value is TimeSpan time)                    return time;                if (TimeSpan.TryParseExact(value as string, "c", CultureInfo.InvariantCulture, TimeSpanStyles.None, out var result))                    return result;                if (TimeSpan.TryParse(value as string, out result))                    return result;                return variable.Deserialize(values.GetEntry(variable.Code));            }            else if (fieldType == typeof(DFLayoutVideoField))            {                if (value is byte[] b)                    return ConvertVideo(b);                else if (value is string str)                {                    if (Guid.TryParse(str, out var id))                        return variable.Deserialize(values.GetEntry(variable.Code));                    try                    {                        var tuple = Serialization.Deserialize<Tuple<Guid, byte[]>>(str, true);                        if (tuple != null)                        {                            return new DFLayoutEmbeddedMediaValue                            {                                ID = tuple.Item1,                                Thumbnail = tuple.Item2,                            };                        }                    }                    catch                    {                    }                    try                    {                        return ConvertVideo(System.Convert.FromBase64String(str));                    }                    catch (Exception e)                    {                        throw new Exception($"Error in video data; invalid Base-64: {e.Message}");                    }                }                return variable.Deserialize(values.GetEntry(variable.Code));            }            else if(fieldType == typeof(DFLayoutAddTaskField))            {                return value?.ToString();            }            else            {                throw new Exception($"Unhandled variable type {fieldType}");            }        }        private bool UpdateForm(Type formType, IDigitalFormInstance instance, DigitalForm form, IList<DigitalFormVariable> variables)        {            var values = DigitalForm.DeserializeFormData(instance);            if(values is null)            {                return false;            }            var save = new DFSaveStorage();            foreach(var variable in variables)            {                try                {                    var value = Deserialize(variable, variable.FieldType(), values);                    variable.Serialize(save.GetEntry(variable.Code), value);                }                catch(Exception e)                {                    Logger.Send(LogType.Error, "", $"Error in data for {variable.Code} ({instance.ID}): {e.Message}");                    save.FormData[variable.Code] = values.GetValue(variable.Code);                    foreach(var (k, v) in values.GetEntry(variable.Code).SubItems())                    {                        save.FormData[$"{variable.Code}.{k}"] = v;                    }                }            }            foreach(var (k, v) in values.Items())            {                if(!save.FormData.ContainsKey(k) && !k.Contains('.') && !variables.Any(x => x.Code == k))                {                    save.FormData[k] = v;                }            }            DigitalForm.SerializeFormData(instance, variables, save);                        return instance.IsChanged();        }    }}
 |