DataEntryPanel.xaml.cs 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. using Comal.Classes;
  2. using InABox.Clients;
  3. using InABox.Core;
  4. using InABox.DynamicGrid;
  5. using InABox.WPF;
  6. using Syncfusion.Data.Extensions;
  7. using Syncfusion.Pdf;
  8. using Syncfusion.Pdf.Graphics;
  9. using System;
  10. using System.Collections.Generic;
  11. using System.Drawing.Imaging;
  12. using System.Drawing;
  13. using System.IO;
  14. using System.Linq;
  15. using System.Text;
  16. using System.Threading.Tasks;
  17. using System.Windows;
  18. using System.Windows.Controls;
  19. using System.Windows.Data;
  20. using System.Windows.Documents;
  21. using System.Windows.Input;
  22. using System.Windows.Media;
  23. using System.Windows.Media.Imaging;
  24. using System.Windows.Navigation;
  25. using Syncfusion.Pdf.Parsing;
  26. using Encoder = System.Drawing.Imaging.Encoder;
  27. using Image = System.Windows.Controls.Image;
  28. using System.Reflection;
  29. namespace PRSDesktop
  30. {
  31. /// <summary>
  32. /// Interaction logic for DataEntryPanel.xaml
  33. /// </summary>
  34. public partial class DataEntryPanel : UserControl, IBasePanel
  35. {
  36. BaseDynamicEditorControl? Popup;
  37. public DataEntryPanel()
  38. {
  39. InitializeComponent();
  40. }
  41. public void Setup()
  42. {
  43. var types = CoreUtils.Entities
  44. .Where(x => x.IsAssignableTo(typeof(Entity))
  45. && x.HasInterface(typeof(IRemotable))
  46. && x.HasInterface(typeof(IPersistent))
  47. && x.GetCustomAttribute<AutoEntity>() is null
  48. && Security.CanEdit(x)
  49. && x.HasInterface<IScannable>())
  50. .Select(x => new Tuple<string, Type?>(x.Name, x)).OrderBy(x => x.Item1).ToList();
  51. types.Insert(0, new("", null));
  52. TypeBox.ItemsSource = types;
  53. TypeBox.DisplayMemberPath = "Item1";
  54. TypeBox.SelectedValuePath = "Item2";
  55. ScanPanel.Setup();
  56. }
  57. public void Refresh()
  58. {
  59. ScanPanel.Refresh();
  60. }
  61. public bool IsReady { get; set; }
  62. public string SectionName => "Data Entry";
  63. public DataModel DataModel(Selection selection)
  64. {
  65. return new EmptyDataModel();
  66. }
  67. public event DataModelUpdateEvent? OnUpdateDataModel;
  68. public void CreateToolbarButtons(IPanelHost host)
  69. {
  70. if (Security.IsAllowed<CanSetupScanTags>())
  71. {
  72. host.CreateSetupAction(new PanelAction
  73. {
  74. Caption = "Scan Tags",
  75. OnExecute = (action) =>
  76. {
  77. var list = new MasterList(typeof(ScanTag));
  78. list.ShowDialog();
  79. }
  80. });
  81. }
  82. }
  83. public void Heartbeat(TimeSpan time)
  84. {
  85. }
  86. public Dictionary<string, object[]> Selected()
  87. {
  88. return new Dictionary<string, object[]>();
  89. }
  90. public void Shutdown()
  91. {
  92. ScanPanel.Shutdown();
  93. }
  94. private void ClearEditor(Type TEntity)
  95. {
  96. UpdateEditor(TEntity, null);
  97. if(Popup is not null)
  98. {
  99. Popup.SetValue(Guid.Empty);
  100. }
  101. }
  102. private bool EditorChanged = false;
  103. private IDynamicDataGrid UpdateEditor(Type TEntity, BaseObject[]? items)
  104. {
  105. DetailGrid.Children.Remove(Editor);
  106. Editor = new EmbeddedDynamicEditorForm();
  107. Editor.SetLayoutType<VerticalDynamicEditorGridLayout>();
  108. Editor.SetValue(Grid.RowProperty, 1);
  109. Editor.SetValue(Grid.ColumnProperty, 0);
  110. Editor.SetValue(Grid.ColumnSpanProperty, 4);
  111. EditorChanged = false;
  112. Editor.OnAfterEditorValueChanged += (sender, column) =>
  113. {
  114. EditorChanged = true;
  115. return null;
  116. };
  117. Editor.OnOK += () =>
  118. {
  119. var cancel = new System.ComponentModel.CancelEventArgs();
  120. Editor.SaveItem(cancel);
  121. if(!cancel.Cancel)
  122. ClearEditor(TEntity);
  123. };
  124. Editor.OnCancel += () =>
  125. {
  126. ClearEditor(TEntity);
  127. };
  128. DetailGrid.Children.Add(Editor);
  129. var grid = DynamicGridUtils.CreateDynamicGrid(typeof(DynamicDataGrid<>), TEntity);
  130. grid.InitialiseEditorForm(Editor, items ?? new object[] { Activator.CreateInstance(TEntity)! });
  131. return (grid as IDynamicDataGrid)!;
  132. }
  133. private void TypeBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
  134. {
  135. var selectedType = TypeBox.SelectedValue as Type;
  136. if (selectedType is not null)
  137. {
  138. var dataGrid = UpdateEditor(selectedType, null);
  139. var editorColumns = dataGrid.LoadEditorColumns();
  140. if (Popup is not null)
  141. DetailGrid.Children.Remove(Popup);
  142. var code = DatabaseSchema.Properties(selectedType)
  143. .Where(x => x.Parent is null && (x.Editor is CodeEditor || x.Editor is UniqueCodeEditor)
  144. && x.Editor.Editable != Editable.Hidden)
  145. .FirstOrDefault();
  146. BaseEditor editor;
  147. if (code is not null)
  148. {
  149. editor = new CodePopupEditor(selectedType) { CodeColumn = code.Name };
  150. Popup = new CodePopupEditorControl { Margin = new Thickness(5), CodeColumn = code.Name };
  151. }
  152. else
  153. {
  154. editor = new PopupEditor(selectedType);
  155. Popup = new PopupEditorControl { Margin = new Thickness(5) };
  156. }
  157. if (Popup is IPopupEditorControl popupEditor)
  158. {
  159. Popup.ColumnName = "ID";
  160. popupEditor.OnDefineFilter += (sender, type) => { return LookupFactory.DefineFilter(type); };
  161. foreach (var column in LookupFactory.DefineColumns(selectedType).ColumnNames().Where(x => x != "ID"))
  162. {
  163. popupEditor.OtherColumns.Add(column, column);
  164. }
  165. if (popupEditor is CodePopupEditorControl codePopup && !popupEditor.OtherColumns.ContainsKey(codePopup.CodeColumn))
  166. {
  167. popupEditor.OtherColumns.Add(codePopup.CodeColumn, codePopup.CodeColumn);
  168. }
  169. }
  170. Popup.SetValue(Grid.RowProperty, 0);
  171. Popup.SetValue(Grid.ColumnProperty, 3);
  172. Popup.EditorDefinition = editor;
  173. Popup.OnEditorValueChanged += (s, v) =>
  174. {
  175. var entityID = (Guid)v["ID"];
  176. BaseObject[]? objs = null;
  177. if (entityID != Guid.Empty)
  178. {
  179. var obj = Client.Create(selectedType)
  180. .Query(
  181. Filter.Create<Entity>(selectedType, x => x.ID).IsEqualTo(entityID),
  182. editorColumns)
  183. .ToObjects(selectedType)
  184. .FirstOrDefault();
  185. if (obj is not null)
  186. {
  187. objs = new BaseObject[] { obj };
  188. }
  189. }
  190. UpdateEditor(selectedType, objs);
  191. };
  192. Popup.Configure();
  193. Popup.Loaded = true;
  194. DetailGrid.Children.Add(Popup);
  195. }
  196. else
  197. {
  198. DetailGrid.Children.Remove(Editor);
  199. if (Popup is not null)
  200. DetailGrid.Children.Remove(Popup);
  201. }
  202. }
  203. private void ScanPanel_OnSelectAppliesTo(string appliesTo)
  204. {
  205. if(CoreUtils.TryGetEntity(appliesTo, out var entity))
  206. {
  207. TypeBox.SelectedValue = entity;
  208. }
  209. }
  210. }
  211. }