DataEntryGrid.cs 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  1. using Comal.Classes;
  2. using InABox.Clients;
  3. using InABox.Core;
  4. using InABox.DynamicGrid;
  5. using InABox.WPF;
  6. using Syncfusion.Pdf;
  7. using System;
  8. using System.Collections.Generic;
  9. using System.IO;
  10. using System.Linq;
  11. using System.Windows;
  12. using System.Windows.Media.Imaging;
  13. namespace PRSDesktop
  14. {
  15. public class DataEntryGrid : DynamicDataGrid<DataEntryDocument>
  16. {
  17. private List<DataEntryTag>? _tags;
  18. public DataEntryGrid()
  19. {
  20. HiddenColumns.Add(x => x.Tag.ID);
  21. HiddenColumns.Add(x => x.Tag.AppliesTo);
  22. HiddenColumns.Add(x => x.Document.ID);
  23. HiddenColumns.Add(x=>x.EntityID);
  24. HiddenColumns.Add(x=>x.Archived);
  25. ActionColumns.Add(new DynamicImageColumn(LinkedImage) { Position = DynamicActionColumnPosition.Start });
  26. }
  27. private static readonly BitmapImage link = PRSDesktop.Resources.link.AsBitmapImage();
  28. private BitmapImage? LinkedImage(CoreRow? arg)
  29. {
  30. return arg == null
  31. ? link
  32. : arg.Get<DataEntryDocument, Guid>(x => x.EntityID) != Guid.Empty
  33. ? link
  34. : null;
  35. }
  36. protected override void DoReconfigure(FluentList<DynamicGridOption> options)
  37. {
  38. base.DoReconfigure(options);
  39. options.BeginUpdate()
  40. .Clear()
  41. .Add(DynamicGridOption.MultiSelect)
  42. .Add(DynamicGridOption.DragSource)
  43. .Add(DynamicGridOption.DragTarget)
  44. .Add(DynamicGridOption.SelectColumns)
  45. .EndUpdate();
  46. }
  47. public static List<DataEntryTag> GetVisibleTagList()
  48. {
  49. var tags = new Client<DataEntryTag>().Query().ToObjects<DataEntryTag>().ToList();
  50. var tagsList = new List<DataEntryTag>();
  51. foreach (var tag in tags)
  52. {
  53. var entity = CoreUtils.GetEntityOrNull(tag.AppliesTo);
  54. if (entity is null || Security.CanView(entity))
  55. {
  56. var tagHasEmployee = new Client<DataEntryTagDistributionEmployee>()
  57. .Query(
  58. new Filter<DataEntryTagDistributionEmployee>(x => x.Tag.ID).IsEqualTo(tag.ID)
  59. .And(x => x.Employee.ID).IsEqualTo(App.EmployeeID),
  60. new Columns<DataEntryTagDistributionEmployee>(x => x.ID))
  61. .Rows.Any();
  62. if (tagHasEmployee)
  63. {
  64. tagsList.Add(tag);
  65. }
  66. }
  67. }
  68. return tagsList;
  69. }
  70. private List<DataEntryTag> GetVisibleTags()
  71. {
  72. _tags ??= GetVisibleTagList();
  73. return _tags;
  74. }
  75. public void DoExplode()
  76. {
  77. Guid tagID = Guid.Empty;
  78. foreach (var row in SelectedRows)
  79. {
  80. var rowTag = row.Get<DataEntryDocument, Guid>(x => x.Tag.ID);
  81. if (tagID == Guid.Empty)
  82. {
  83. tagID = rowTag;
  84. }
  85. else if (rowTag != tagID)
  86. {
  87. tagID = Guid.Empty;
  88. break;
  89. }
  90. }
  91. var docIDs = SelectedRows.Select(r => r.Get<DataEntryDocument, Guid>(c => c.Document.ID)).ToArray();
  92. var docs = new Client<Document>()
  93. .Query(
  94. new Filter<Document>(x => x.ID).InList(docIDs),
  95. new Columns<Document>(x => x.ID).Add(x => x.Data).Add(x => x.FileName))
  96. .ToObjects<Document>().ToDictionary(x => x.ID, x => x);
  97. var pages = new List<DataEntryReGroupWindow.Page>();
  98. string filename = "";
  99. foreach (var docID in docIDs)
  100. {
  101. if (docs.TryGetValue(docID, out var doc))
  102. {
  103. filename = doc.FileName;
  104. var ms = new MemoryStream(doc.Data);
  105. var pdfDoc = DataEntryReGroupWindow.RenderToPDF(doc.FileName, ms);
  106. foreach (var page in DataEntryReGroupWindow.SplitIntoPages(doc.FileName, pdfDoc))
  107. {
  108. pages.Add(page);
  109. }
  110. }
  111. }
  112. if (ShowDocumentWindow(pages, filename, tagID))
  113. {
  114. // ShowDocumentWindow already saves new scans, so we just need to get rid of the old ones.
  115. DeleteItems(SelectedRows);
  116. Refresh(false,true);
  117. }
  118. }
  119. public void DoRemove()
  120. {
  121. var updates = SelectedRows.Select(x => x.ToObject<DataEntryDocument>()).ToArray();
  122. foreach (var update in updates)
  123. update.Archived = DateTime.Now;
  124. new Client<DataEntryDocument>().Save(updates,"Removed from Data Entry Panel");
  125. Refresh(false,true);
  126. }
  127. public void DoChangeTags(Guid tagid)
  128. {
  129. var updates = SelectedRows.Select(x => x.ToObject<DataEntryDocument>()).ToArray();
  130. foreach (var update in updates)
  131. {
  132. if (update.Tag.ID != tagid)
  133. {
  134. update.Tag.ID = tagid;
  135. update.EntityID = Guid.Empty;
  136. }
  137. }
  138. new Client<DataEntryDocument>().Save(updates.Where(x=>x.IsChanged()),"Updated Tags on Data Entry Panel");
  139. Refresh(false,true);
  140. }
  141. protected override DragDropEffects OnRowsDragStart(CoreRow[] rows)
  142. {
  143. var table = new CoreTable();
  144. table.Columns.Add(new CoreColumn { ColumnName = "ID", DataType = typeof(Guid) });
  145. foreach(var row in rows)
  146. {
  147. var newRow = table.NewRow();
  148. newRow.Set<Document, Guid>(x => x.ID, row.Get<DataEntryDocument, Guid>(x => x.Document.ID));
  149. table.Rows.Add(newRow);
  150. }
  151. return DragTable(typeof(Document), table);
  152. }
  153. public void UploadDocument(string filename, byte[] data, Guid tagID)
  154. {
  155. var document = new Document
  156. {
  157. FileName = filename,
  158. CRC = CoreUtils.CalculateCRC(data),
  159. TimeStamp = DateTime.Now,
  160. Data = data
  161. };
  162. new Client<Document>().Save(document, "");
  163. var dataentry = new DataEntryDocument
  164. {
  165. Document =
  166. {
  167. ID = document.ID
  168. },
  169. Tag =
  170. {
  171. ID = tagID
  172. },
  173. Employee =
  174. {
  175. ID = App.EmployeeID
  176. },
  177. Thumbnail = ImageUtils.GetPDFThumbnail(data, 256, 256)
  178. };
  179. new Client<DataEntryDocument>().Save(dataentry, "");
  180. Dispatcher.Invoke(() =>
  181. {
  182. Refresh(false, true);
  183. });
  184. }
  185. private static PdfDocumentBase CombinePages(IEnumerable<DataEntryReGroupWindow.Page> pages)
  186. {
  187. var document = new PdfDocument();
  188. foreach (var page in pages)
  189. {
  190. document.ImportPage(page.Pdf, page.PageIndex);
  191. }
  192. return document;
  193. }
  194. public bool ShowDocumentWindow(List<DataEntryReGroupWindow.Page> pages, string filename, Guid tagID)
  195. {
  196. var window = new DataEntryReGroupWindow(pages, filename, tagID);
  197. if (window.ShowDialog() == true)
  198. {
  199. Progress.ShowModal("Uploading Files", (progress) =>
  200. {
  201. foreach (var group in window.Groups)
  202. {
  203. progress.Report($"Uploading '{group.FileName}'");
  204. var doc = CombinePages(group.Pages);
  205. byte[] data;
  206. using (var ms = new MemoryStream())
  207. {
  208. doc.Save(ms);
  209. data = ms.ToArray();
  210. }
  211. UploadDocument(group.FileName, data, group.TagID);
  212. }
  213. });
  214. return true;
  215. }
  216. return false;
  217. }
  218. protected override void GenerateColumns(DynamicGridColumns columns)
  219. {
  220. columns.Add<DataEntryDocument, string>(x => x.Document.FileName, 0, "Filename", "", Alignment.MiddleLeft);
  221. columns.Add<DataEntryDocument, string>(x => x.Tag.Name, 100, "Tag", "", Alignment.MiddleLeft);
  222. }
  223. protected override void Reload(Filters<DataEntryDocument> criteria, Columns<DataEntryDocument> columns, ref SortOrder<DataEntryDocument>? sort, Action<CoreTable?, Exception?> action)
  224. {
  225. criteria.Add(new Filter<DataEntryDocument>(x => x.Archived).IsEqualTo(DateTime.MinValue));
  226. var tagFilter = new Filter<DataEntryDocument>(x => x.Tag.ID).InList(GetVisibleTags().Select(x => x.ID).ToArray());
  227. if (Security.IsAllowed<CanSetupDataEntryTags>())
  228. {
  229. tagFilter.Or(x => x.Tag.ID).IsEqualTo(Guid.Empty);
  230. }
  231. criteria.Add(tagFilter);
  232. base.Reload(criteria, columns, ref sort, action);
  233. }
  234. }
  235. }