using Comal.Classes; using InABox.Clients; using InABox.Core; using InABox.DynamicGrid; using InABox.WPF; using Syncfusion.Pdf; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Windows.Media.Imaging; namespace PRSDesktop { public class DataEntryGrid : DynamicDataGrid { private List? _tags; public DataEntryGrid() { HiddenColumns.Add(x => x.Tag.ID); HiddenColumns.Add(x => x.Tag.AppliesTo); HiddenColumns.Add(x => x.Document.ID); HiddenColumns.Add(x=>x.EntityID); HiddenColumns.Add(x=>x.Archived); ActionColumns.Add(new DynamicImageColumn(LinkedImage) { Position = DynamicActionColumnPosition.Start }); } private static readonly BitmapImage link = PRSDesktop.Resources.link.AsBitmapImage(); private BitmapImage? LinkedImage(CoreRow? arg) { return arg == null ? link : arg.Get(x => x.EntityID) != Guid.Empty ? link : null; } protected override void DoReconfigure(FluentList options) { base.DoReconfigure(options); options.BeginUpdate() .Clear() .Add(DynamicGridOption.MultiSelect) .Add(DynamicGridOption.DragSource) .Add(DynamicGridOption.SelectColumns) .EndUpdate(); } public static List GetVisibleTagList() { var tags = new Client().Query().ToObjects().ToList(); var tagsList = new List(); foreach (var tag in tags) { var entity = CoreUtils.GetEntityOrNull(tag.AppliesTo); if (entity is null || Security.CanView(entity)) { var tagHasEmployee = new Client() .Query( new Filter(x => x.Tag.ID).IsEqualTo(tag.ID) .And(x => x.Employee.ID).IsEqualTo(App.EmployeeID), new Columns(x => x.ID)) .Rows.Any(); if (tagHasEmployee) { tagsList.Add(tag); } } } return tagsList; } private List GetVisibleTags() { _tags ??= GetVisibleTagList(); return _tags; } public void DoExplode() { Guid tagID = Guid.Empty; foreach (var row in SelectedRows) { var rowTag = row.Get(x => x.Tag.ID); if (tagID == Guid.Empty) { tagID = rowTag; } else if (rowTag != tagID) { tagID = Guid.Empty; break; } } var docIDs = SelectedRows.Select(r => r.Get(c => c.Document.ID)).ToArray(); var docs = new Client() .Query( new Filter(x => x.ID).InList(docIDs), new Columns(x => x.ID).Add(x => x.Data).Add(x => x.FileName)) .ToObjects().ToDictionary(x => x.ID, x => x); var pages = new List(); string filename = ""; foreach (var docID in docIDs) { if (docs.TryGetValue(docID, out var doc)) { filename = doc.FileName; var ms = new MemoryStream(doc.Data); var pdfDoc = DataEntryReGroupWindow.RenderToPDF(doc.FileName, ms); foreach (var page in DataEntryReGroupWindow.SplitIntoPages(doc.FileName, pdfDoc)) { pages.Add(page); } } } if (ShowDocumentWindow(pages, filename, tagID)) { // ShowDocumentWindow already saves new scans, so we just need to get rid of the old ones. DeleteItems(SelectedRows); Refresh(false,true); } } public void DoRemove() { var updates = SelectedRows.Select(x => x.ToObject()).ToArray(); foreach (var update in updates) update.Archived = DateTime.Now; new Client().Save(updates,"Removed from Data Entry Panel"); Refresh(false,true); } public void DoChangeTags(Guid tagid) { var updates = SelectedRows.Select(x => x.ToObject()).ToArray(); foreach (var update in updates) { if (update.Tag.ID != tagid) { update.Tag.ID = tagid; update.EntityID = Guid.Empty; } } new Client().Save(updates.Where(x=>x.IsChanged()),"Updated Tags on Data Entry Panel"); Refresh(false,true); } protected override void OnRowsDragStart(CoreRow[] rows) { var table = new CoreTable(); table.Columns.Add(new CoreColumn { ColumnName = "ID", DataType = typeof(Guid) }); foreach(var row in rows) { var newRow = table.NewRow(); newRow.Set(x => x.ID, row.Get(x => x.Document.ID)); table.Rows.Add(newRow); } DragTable(typeof(Document), table); } public void UploadDocument(string filename, byte[] data, Guid tagID) { var document = new Document { FileName = filename, CRC = CoreUtils.CalculateCRC(data), TimeStamp = DateTime.Now, Data = data }; new Client().Save(document, ""); var dataentry = new DataEntryDocument { Document = { ID = document.ID }, Tag = { ID = tagID }, Employee = { ID = App.EmployeeID }, Thumbnail = ImageUtils.GetPDFThumbnail(data, 256, 256) }; new Client().Save(dataentry, ""); Dispatcher.Invoke(() => { Refresh(false, true); }); } private static PdfDocumentBase CombinePages(IEnumerable pages) { var document = new PdfDocument(); foreach (var page in pages) { document.ImportPage(page.Pdf, page.PageIndex); } return document; } public bool ShowDocumentWindow(List pages, string filename, Guid tagID) { var window = new DataEntryReGroupWindow(pages, filename, tagID); if (window.ShowDialog() == true) { Progress.ShowModal("Uploading Files", (progress) => { foreach (var group in window.Groups) { progress.Report($"Uploading '{group.FileName}'"); var doc = CombinePages(group.Pages); byte[] data; using (var ms = new MemoryStream()) { doc.Save(ms); data = ms.ToArray(); } UploadDocument(group.FileName, data, group.TagID); } }); return true; } return false; } protected override void GenerateColumns(DynamicGridColumns columns) { columns.Add(x => x.Document.FileName, 0, "Filename", "", Alignment.MiddleLeft); columns.Add(x => x.Tag.Name, 100, "Tag", "", Alignment.MiddleLeft); } protected override void Reload(Filters criteria, Columns columns, ref SortOrder? sort, Action action) { criteria.Add(new Filter(x => x.Archived).IsEqualTo(DateTime.MinValue)); var tagFilter = new Filter(x => x.Tag.ID).InList(GetVisibleTags().Select(x => x.ID).ToArray()); if (Security.IsAllowed()) { tagFilter.Or(x => x.Tag.ID).IsEqualTo(Guid.Empty); } criteria.Add(tagFilter); base.Reload(criteria, columns, ref sort, action); } } }