123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378 |
- using Comal.Classes;
- using InABox.Clients;
- using InABox.Configuration;
- using InABox.Core;
- using InABox.DynamicGrid;
- using InABox.WPF;
- using PRSDesktop.Panels.DataEntry;
- using Syncfusion.Pdf;
- using System;
- using System.Collections.Generic;
- using System.IO;
- using System.Linq;
- using System.Threading;
- using System.Windows;
- using System.Windows.Media.Imaging;
- namespace PRSDesktop;
- public class DataEntryCache : DocumentCache
- {
- public override TimeSpan MaxAge => TimeSpan.FromDays(new UserConfiguration<DataEntryPanelSettings>().Load().CacheAge);
- private static DataEntryCache? _cache;
- public static DataEntryCache Cache
- {
- get
- {
- _cache ??= DocumentCaches.GetOrRegister<DataEntryCache>();
- return _cache;
- }
- }
- public DataEntryCache(): base(nameof(DataEntryCache)) { }
- }
- public class DataEntryGrid : DynamicDataGrid<DataEntryDocument>
- {
- private List<DataEntryTag>? _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.Document.FileName);
- HiddenColumns.Add(x => x.EntityID);
- HiddenColumns.Add(x => x.Archived);
- HiddenColumns.Add(x => x.Note);
-
- ActionColumns.Add(new DynamicImageColumn(LinkedImage) { Position = DynamicActionColumnPosition.Start });
- var tagFilter = new Filter<DataEntryDocument>(x => x.Tag.ID).InList(GetVisibleTags().Select(x => x.ID).ToArray());
- if (Security.IsAllowed<CanSetupDataEntryTags>())
- {
- tagFilter.Or(x => x.Tag.ID).IsEqualTo(Guid.Empty);
- }
- var docs = Client.Query(
- new Filter<DataEntryDocument>(x => x.Archived).IsEqualTo(DateTime.MinValue)
- .And(tagFilter),
- Columns.None<DataEntryDocument>().Add(x => x.Document.ID));
- DataEntryCache.Cache.ClearOld();
- DataEntryCache.Cache.EnsureStrict(docs.Rows.Select(x => x.Get<DataEntryDocument, Guid>(x => x.Document.ID)).ToArray());
- }
- private static readonly BitmapImage link = PRSDesktop.Resources.link.AsBitmapImage();
-
- private BitmapImage? LinkedImage(CoreRow? arg)
- {
- return arg == null
- ? link
- : arg.Get<DataEntryDocument, Guid>(x => x.EntityID) != Guid.Empty
- ? link
- : null;
- }
- protected override void DoReconfigure(DynamicGridOptions options)
- {
- base.DoReconfigure(options);
- options.Clear();
- options.FilterRows = true;
- options.MultiSelect = true;
- options.DragSource = true;
- options.DragTarget = true;
- options.SelectColumns = true;
- }
-
- public static List<DataEntryTag> GetVisibleTagList()
- {
- var tags = new Client<DataEntryTag>().Query().ToObjects<DataEntryTag>().ToList();
- var tagsList = new List<DataEntryTag>();
- foreach (var tag in tags)
- {
- var entity = CoreUtils.GetEntityOrNull(tag.AppliesTo);
- if (entity is null || Security.CanView(entity))
- {
- var tagHasEmployee = new Client<DataEntryTagDistributionEmployee>()
- .Query(
- new Filter<DataEntryTagDistributionEmployee>(x => x.Tag.ID).IsEqualTo(tag.ID)
- .And(x => x.Employee.ID).IsEqualTo(App.EmployeeID),
- Columns.None<DataEntryTagDistributionEmployee>().Add(x => x.ID))
- .Rows.Any();
- if (tagHasEmployee)
- {
- tagsList.Add(tag);
- }
- }
- }
- return tagsList;
- }
- private List<DataEntryTag> GetVisibleTags()
- {
- _tags ??= GetVisibleTagList();
- return _tags;
- }
- /// <summary>
- /// Gets the currently selected tag ID, if all selected rows belong to the same tag.
- /// </summary>
- /// <returns></returns>
- private Guid GetSelectedTagID()
- {
- var tagID = Guid.Empty;
- foreach (var row in SelectedRows)
- {
- var rowTag = row.Get<DataEntryDocument, Guid>(x => x.Tag.ID);
- if (tagID == Guid.Empty)
- {
- tagID = rowTag;
- }
- else if (rowTag != tagID)
- {
- return Guid.Empty;
- }
- }
- return tagID;
- }
- private IEnumerable<Tuple<DataEntryDocument, List<DataEntryReGroupWindow.Page>>> ExplodeDocuments()
- {
- var dataEntryDocs = SelectedRows.ToArray<DataEntryDocument>();
- var docIDs = dataEntryDocs.Select(r => r.Document.ID).ToArray();
- var docs = new Client<Document>()
- .Query(
- new Filter<Document>(x => x.ID).InList(docIDs),
- Columns.None<Document>().Add(x => x.ID).Add(x => x.Data).Add(x => x.FileName))
- .ToObjects<Document>().ToDictionary(x => x.ID, x => x);
- foreach (var dataEntryDoc in dataEntryDocs)
- {
- if (docs.TryGetValue(dataEntryDoc.Document.ID, out var doc))
- {
- var ms = new MemoryStream(doc.Data);
- var pdfDoc = DataEntryReGroupWindow.RenderToPDF(doc.FileName, ms);
- yield return new(dataEntryDoc, DataEntryReGroupWindow.SplitIntoPages(doc.FileName, pdfDoc).ToList());
- }
- }
- }
- public void DoExplodeAll()
- {
- var pages = ExplodeDocuments();
- var groups = new List<DocumentGroup>();
- foreach(var (doc, docPages) in pages)
- {
- if(docPages.Count == 1)
- {
- groups.Add(new DocumentGroup(doc.Document.FileName, docPages, doc.Tag.ID));
- }
- else
- {
- var extension = Path.GetExtension(doc.Document.FileName) ?? "";
- var stem = Path.GetFileNameWithoutExtension(doc.Document.FileName);
- foreach(var (i, page) in docPages.WithIndex())
- {
- var group = new DocumentGroup($"{stem} - {i + 1}{extension}", [page], doc.Tag.ID);
- groups.Add(group);
- }
- }
- }
- SavePageGroups(groups);
- DeleteItems(SelectedRows);
- Refresh(false,true);
- }
-
- public void DoExplode()
- {
- var tagID = GetSelectedTagID();
- var pages = ExplodeDocuments();
- var filename = "";
- var allPages = new List<DataEntryReGroupWindow.Page>();
- foreach(var (doc, docPages) in pages)
- {
- filename = doc.Document.FileName;
- allPages.AddRange(docPages);
- }
- if (ShowDocumentWindow(allPages, 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<DataEntryDocument>()).ToArray();
- foreach (var update in updates)
- {
- update.Archived = DateTime.Now;
- DataEntryCache.Cache.Remove(update.Document.ID);
- }
- new Client<DataEntryDocument>().Save(updates,"Removed from Data Entry Panel");
- Refresh(false,true);
- }
- public void DoChangeTags(Guid tagid)
- {
- var updates = SelectedRows.Select(x => x.ToObject<DataEntryDocument>()).ToArray();
- foreach (var update in updates)
- {
- if (update.Tag.ID != tagid)
- {
- update.Tag.ID = tagid;
- update.EntityID = Guid.Empty;
- }
- }
- new Client<DataEntryDocument>().Save(updates.Where(x=>x.IsChanged()),"Updated Tags on Data Entry Panel");
- Refresh(false,true);
- }
- public void DoChangeNote(string note)
- {
- var updates = SelectedRows.ToObjects<DataEntryDocument>().ToArray();
- foreach (var update in updates)
- {
- if (!string.Equals(update.Note, note))
- {
- update.Note = note;
- }
- }
- Client.Save(updates.Where(x => x.IsChanged()), "Updated Note on Data Entry Panel");
- Refresh(false, true);
- }
-
- protected override DragDropEffects 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<Document, Guid>(x => x.ID, row.Get<DataEntryDocument, Guid>(x => x.Document.ID));
- table.Rows.Add(newRow);
- }
- return 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<Document>().Save(document, "");
- var dataentry = new DataEntryDocument
- {
- Document =
- {
- ID = document.ID
- },
- Tag =
- {
- ID = tagID
- },
- Employee =
- {
- ID = App.EmployeeID
- }
- };
- if(Path.GetExtension(filename) == ".pdf")
- {
- dataentry.Thumbnail = ImageUtils.GetPDFThumbnail(data, 256, 256);
- }
- new Client<DataEntryDocument>().Save(dataentry, "");
- DataEntryCache.Cache.Add(new DocumentCachedDocument(document));
- Dispatcher.BeginInvoke(() =>
- {
- Refresh(false, true);
- });
- }
- private static PdfDocumentBase CombinePages(IEnumerable<DataEntryReGroupWindow.Page> pages)
- {
- var document = new PdfDocument();
- foreach (var page in pages)
- {
- document.ImportPage(page.Pdf, page.PageIndex);
- }
- return document;
- }
- private void SavePageGroups(IEnumerable<DocumentGroup> groups)
- {
- Progress.ShowModal("Uploading Files", (progress) =>
- {
- foreach (var group in 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);
- }
- });
- }
- public bool ShowDocumentWindow(List<DataEntryReGroupWindow.Page> pages, string filename, Guid tagID)
- {
- var window = new DataEntryReGroupWindow(pages, filename, tagID);
- if (window.ShowDialog() == true)
- {
- SavePageGroups(window.Groups);
- return true;
- }
- return false;
- }
-
- public override DynamicGridColumns GenerateColumns()
- {
- var columns = new DynamicGridColumns();
- columns.Add<DataEntryDocument, string>(x => x.Document.FileName, 0, "Filename", "", Alignment.MiddleLeft);
- columns.Add<DataEntryDocument, string>(x => x.Tag.Name, 100, "Tag", "", Alignment.MiddleLeft);
- return columns;
- }
- protected override void Reload(
- Filters<DataEntryDocument> criteria, Columns<DataEntryDocument> columns, ref SortOrder<DataEntryDocument>? sort,
- CancellationToken token, Action<CoreTable?, Exception?> action)
- {
- criteria.Add(new Filter<DataEntryDocument>(x => x.Archived).IsEqualTo(DateTime.MinValue));
- var tagFilter = new Filter<DataEntryDocument>(x => x.Tag.ID).InList(GetVisibleTags().Select(x => x.ID).ToArray());
- if (Security.IsAllowed<CanSetupDataEntryTags>())
- {
- tagFilter.Or(x => x.Tag.ID).IsEqualTo(Guid.Empty);
- }
- criteria.Add(tagFilter);
- base.Reload(criteria, columns, ref sort, token, action);
- }
- }
|