DataEntryGrid.cs 9.2 KB

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