DigitalFormReportDataModel.cs 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using InABox.Clients;
  5. using System.Diagnostics.CodeAnalysis;
  6. namespace InABox.Core
  7. {
  8. public interface IDigitalFormReportDataModel
  9. {
  10. public DigitalFormVariable[]? Variables { get; set; }
  11. void AddFormData(Guid formInstanceID, DFLoadStorage storage);
  12. }
  13. /// <summary>
  14. /// </summary>
  15. /// <typeparam name="T">
  16. /// Should always be an EntityForm<,></typeparam>
  17. public class DigitalFormReportDataModel<T> : AutoDataModel<T>, IDigitalFormReportDataModel
  18. where T : Entity, IRemotable, IPersistent, IDigitalFormInstance, new()
  19. {
  20. private Guid? FormId { get; set; } = null;
  21. private CoreTable? FormDataTable { get; set; } = null;
  22. private Dictionary<Guid, DFLoadStorage> FormData { get; set; } = new Dictionary<Guid, DFLoadStorage>();
  23. //private DigitalFormVariable[]? _variables = null;
  24. public DigitalFormVariable[]? Variables { get; set; }
  25. public DigitalFormReportDataModel(Filter<T> filter, Guid? formId = null) : base(filter)
  26. {
  27. FormId = formId;
  28. }
  29. public override string Name => "Digital Form Reports";
  30. public void AddFormData(Guid formInstanceID, DFLoadStorage storage)
  31. {
  32. FormData.Add(formInstanceID, storage);
  33. }
  34. protected override void CheckRequiredTables(List<string> requiredtables)
  35. {
  36. base.CheckRequiredTables(requiredtables);
  37. requiredtables.Add(TableName<T>());
  38. }
  39. private void LoadFormDataTable(Guid formID)
  40. {
  41. var formDataTable = new CoreTable();
  42. formDataTable.Columns.Add(new CoreColumn
  43. {
  44. ColumnName = "Parent.ID",
  45. DataType = typeof(Guid)
  46. });
  47. Variables ??= new Client<DigitalFormVariable>().Load(new Filter<DigitalFormVariable>(x => x.Form.ID).IsEqualTo(formID));
  48. foreach (var variable in Variables)
  49. {
  50. var columns = variable.GetDisplayColumns().ToArray();
  51. foreach (var column in columns)
  52. formDataTable.Columns.Add(column);
  53. }
  54. FormDataTable = formDataTable;
  55. AddTable("Form_Data", formDataTable, isdefault: true);
  56. LinkTable(typeof(T), "ID", "Form_Data", "Parent.ID");
  57. }
  58. private void LoadFormDataIntoRow(CoreRow row, DFLoadStorage data)
  59. {
  60. foreach(var variable in Variables!)
  61. {
  62. var value = variable.Deserialize(data.GetEntry(variable.Code));
  63. foreach(var (k, v) in variable.GetDisplayValues(value))
  64. {
  65. row[k] = v;
  66. }
  67. }
  68. }
  69. protected override void AfterLoad(IEnumerable<string> requiredtables)
  70. {
  71. base.AfterLoad(requiredtables);
  72. if(FormDataTable == null)
  73. {
  74. LoadFormDataTable(FormId ?? ExtractValues<T, Guid>(x => x.Form.ID).FirstOrDefault());
  75. }
  76. var idList = ExtractValues<T, Guid>(x => x.ID);
  77. var jsonLists = ExtractValues<T, string>(x => x.FormData, false).ToList();
  78. var blobLists = ExtractValues<T, string?>(x => x.BlobData, false).ToList();
  79. for(var i = 0; i < jsonLists.Count; ++i)
  80. {
  81. if (!FormData.TryGetValue(idList[i], out var formData))
  82. {
  83. var json = jsonLists[i];
  84. var blobJSON = blobLists[i];
  85. formData = DigitalForm.DeserializeFormData(json, blobJSON);
  86. }
  87. var formRow = FormDataTable!.NewRow();
  88. formRow["Parent.ID"] = idList[i];
  89. if (formData != null) LoadFormDataIntoRow(formRow, formData);
  90. FormDataTable.Rows.Add(formRow);
  91. }
  92. Load(typeof(CoreTable), FormDataTable!, requiredtables, "Form_Data");
  93. }
  94. public string? EvaluateExpression(string expression)
  95. {
  96. if (string.IsNullOrWhiteSpace(expression))
  97. return null;
  98. Dictionary<string, object?> variables = new Dictionary<string, object?>();
  99. var formrow = FormDataTable.Rows.FirstOrDefault();
  100. foreach (var column in FormDataTable.Columns)
  101. variables[$"Data.{column.ColumnName}"] = formrow?[column.ColumnName];
  102. var instancetable = GetTable<T>();
  103. var instancerow = instancetable.Rows.FirstOrDefault();
  104. foreach (var column in instancetable.Columns)
  105. variables[$"Form.{column.ColumnName}"] = instancerow?[column.ColumnName];
  106. var inter = typeof(T)
  107. .GetInterfaces()
  108. .FirstOrDefault(x => x.IsGenericType && x.GetGenericTypeDefinition() == typeof(IDigitalFormInstance<>));
  109. if (inter != null)
  110. {
  111. var link = inter.GenericTypeArguments[0];
  112. var entityLinkDef = link.GetSuperclassDefinition(typeof(EntityLink<>));
  113. if (entityLinkDef != null)
  114. {
  115. var entityType = entityLinkDef.GenericTypeArguments[0];
  116. var parenttablename = $"{DataModel.TableName(typeof(T))}_{DataModel.TableName(entityType)}";
  117. var entitytable = GetDataModelTable(parenttablename);
  118. if (entitytable != null)
  119. {
  120. foreach (var column in entitytable.Table.Columns)
  121. variables[$"{entityType.EntityName().Split('.').Last()}.{column.ColumnName}"] =
  122. instancerow?[column.ColumnName];
  123. }
  124. }
  125. }
  126. var exp = new CoreExpression(expression);
  127. return exp.Evaluate(variables)?.ToString();
  128. }
  129. }
  130. }