Explorar el Código

Refactored StagingSetoutGrid

Kenric Nugteren hace 2 años
padre
commit
571bb7aa53
Se han modificado 1 ficheros con 119 adiciones y 114 borrados
  1. 119 114
      prs.desktop/Panels/Staging/Setouts/StagingSetoutGrid.cs

+ 119 - 114
prs.desktop/Panels/Staging/Setouts/StagingSetoutGrid.cs

@@ -25,12 +25,27 @@ namespace PRSDesktop
 {
     public class StagingSetoutGrid : DynamicDataGrid<StagingSetout>
     {
-        public delegate void CustomiseSetoutsEvent(IReadOnlyList<StagingSetout> setouts);
+        public class SetoutDocument
+        {
+            public Document Document { get; set; }
 
-        public event CustomiseSetoutsEvent? OnCustomiseSetouts;
+            public StagingSetout Setout { get; set; }
 
-        private List<Document> _existingFiles = new();
-        private Job[]? _jobs = null;
+            public SetoutDocument(Document document, StagingSetout setout)
+            {
+                Document = document;
+                Setout = setout;
+            }
+
+            public void Deconstruct(out Document document, out StagingSetout setout)
+            {
+                document = Document;
+                setout = Setout;
+            }
+        }
+        public delegate void CustomiseSetoutsEvent(IReadOnlyList<SetoutDocument> setouts);
+
+        public event CustomiseSetoutsEvent? OnCustomiseSetouts;
 
         public StagingSetoutGrid()
         {
@@ -67,9 +82,7 @@ namespace PRSDesktop
                 return false;
             }
 
-            List<StagingSetout> list = new List<StagingSetout>();
-            foreach (var row in rows)
-                list.Add(row.ToObject<StagingSetout>());
+            var list = rows.Select(x => x.ToObject<StagingSetout>()).ToList();
 
             string message = "";
             foreach (var staging in list)
@@ -94,88 +107,93 @@ namespace PRSDesktop
 
         protected override void DoAdd(bool OpenEditorOnDirectEdit = false)
         {
-            var dlg = new OpenFileDialog();
-            dlg.Multiselect = true;
-            dlg.Title = "Add Staging Files";
-            dlg.Filter = "PDF Files (*.pdf)|*.pdf";
+            var dlg = new OpenFileDialog
+            {
+                Multiselect = true,
+                Title = "Add Staging Files",
+                Filter = "PDF Files (*.pdf)|*.pdf"
+            };
             if (dlg.ShowDialog() == true)
                 AddFiles(dlg.FileNames);
         }
 
-        private Job[] GetJobs()
-        {
-            _jobs ??= new Client<Job>().Query(null, new Columns<Job>(x => x.ID, x => x.JobNumber, x => x.Name))
-                .ToObjects<Job>().ToArray();
-            return _jobs;
-        }
-
         public void AddFiles(string[] fileNames)
         {
-            LoadExistingStaging();
-
-            var documents = new List<Document>();
             var stagingdocs = new List<StagingSetoutDocument>();
 
             var cancel = new CancelEventArgs();
-            foreach (var file in fileNames)
+
+            var newDocuments = fileNames.Select(x =>
             {
-                var document = ReadFile(file);
-                if (!CheckSetoutClash(document, cancel))
+                var file = ReadFile(x);
+                return new SetoutDocument(file, new StagingSetout
                 {
-                    if (cancel.Cancel)
-                    {
-                        return;
-                    }
-                    else
+                    Number = file.FileName
+                });
+            }).ToList();
+
+            var checkNumbers = newDocuments.Select(x => x.Setout.Number).ToArray();
+            var clashSetouts = new Client<StagingSetout>()
+                .Query(
+                    new Filter<StagingSetout>(x => x.Number).InList(checkNumbers),
+                    new Columns<StagingSetout>(x => x.ID).Add(x => x.Number))
+                .ToObjects<StagingSetout>().ToList();
+
+            var setoutsToDelete = new List<StagingSetout>();
+            if (clashSetouts.Any())
+            {
+                var setoutDocuments = new Client<StagingSetoutDocument>()
+                    .Query(
+                        new Filter<StagingSetoutDocument>(x => x.EntityLink.ID).InList(clashSetouts.Select(x => x.ID).ToArray()),
+                        new Columns<StagingSetoutDocument>(x => x.ID).Add(x => x.EntityLink.ID).Add(x => x.DocumentLink.CRC));
+
+                foreach(var doc in setoutDocuments.ToObjects<StagingSetoutDocument>())
+                {
+                    // This setout must exist based on the filter.
+                    var setout = clashSetouts.First(x => x.ID == doc.EntityLink.ID);
+
+                    // This document must exist also based on the filter.
+                    var newDoc = newDocuments.First(x => x.Setout.Number == setout.Number);
+                    if(doc.DocumentLink.CRC != newDoc.Document.CRC)
                     {
-                        continue;
+                        // We only care if the CRC is different, because this means the same file is being re-uploaded.
+                        var result = MessageBox.Show($"A different setout with the number '{setout.Number}' already exists. Do you wish to replace the existing setout with the new one?", "Replace Existing", MessageBoxButton.YesNoCancel);
+                        if (result == MessageBoxResult.Yes)
+                        {
+                            setoutsToDelete.Add(setout);
+                        }
+                        else if(result == MessageBoxResult.No)
+                        {
+                            newDocuments.Remove(newDoc);
+                        }
+                        else if (result == MessageBoxResult.Cancel)
+                        {
+                            return;
+                        }
                     }
                 }
-
-                documents.Add(document);
             }
 
-            new Client<Document>().Save(documents, "Created from sync setout function");
-
-            var stagingSetouts = documents.Select(x => new StagingSetout
-            {
-                Number = x.FileName
-            }).ToArray();
+            new Client<Document>().Save(newDocuments.Select(x => x.Document), "Created from sync setout function");
 
-            OnCustomiseSetouts?.Invoke(stagingSetouts);
-            new Client<StagingSetout>().Save(stagingSetouts, "Created from sync setout function");
+            OnCustomiseSetouts?.Invoke(newDocuments);
+            new Client<StagingSetout>().Save(newDocuments.Select(x => x.Setout), "Created from sync setout function");
 
-            for(int i = 0; i < documents.Count; ++i)
+            foreach(var (doc, setout) in newDocuments)
             {
                 var stagingsetoutdoc = new StagingSetoutDocument();
-                stagingsetoutdoc.EntityLink.ID = stagingSetouts[i].ID;
-                stagingsetoutdoc.DocumentLink.ID = documents[i].ID;
+                stagingsetoutdoc.EntityLink.ID = setout.ID;
+                stagingsetoutdoc.DocumentLink.ID = doc.ID;
                 stagingdocs.Add(stagingsetoutdoc);
             }
             new Client<StagingSetoutDocument>().Save(stagingdocs, "Created from sync setout function");
 
-            Refresh(false, true);
-        }
-
-        private void UpdateStagingDocument(string file)
-        {
-            var table = new Client<StagingSetoutDocument>()
-                .Query(new Filter<StagingSetoutDocument>(x => x.DocumentLink.FileName).IsEqualTo(Path.GetFileName(file)));
-            if (table.Rows.Any())
+            foreach(var setout in setoutsToDelete)
             {
-                var stagingSetoutDoc = table.Rows.First().ToObject<StagingSetoutDocument>();
-
-                var doc = ReadFile(file);
-                new Client<Document>().Save(doc, "Created from Staging Setout Screen");
-                stagingSetoutDoc.DocumentLink.ID = doc.ID;
-                new Client<StagingSetoutDocument>().Save(stagingSetoutDoc, "Updated from Staging Setout Screen");
+                new Client<StagingSetout>().Delete(setout, "Replaced by new setout");
             }
-        }
 
-        private Guid TryFindJob(string filePreFix)
-        {
-            var job = GetJobs().FirstOrDefault(x => x.JobNumber.Equals(filePreFix.Substring(0, 4)) || x.JobNumber.Equals(filePreFix.Substring(0, 5)) || x.JobNumber.Equals(filePreFix.Substring(0, 6)));
-            return job == null ? Guid.Empty : job.ID;
+            Refresh(false, true);
         }
 
         /// <summary>
@@ -183,16 +201,18 @@ namespace PRSDesktop
         /// </summary>
         /// <param name="file"></param>
         /// <returns></returns>
-        private Document ReadFile(string file)
+        private static Document ReadFile(string file)
         {
-            Document doc = new Document();
-            doc.FileName = Path.GetFileName(file);
-            doc.Data = GetData(file);
+            var doc = new Document
+            {
+                FileName = Path.GetFileName(file),
+                Data = GetData(file)
+            };
             doc.CRC = CoreUtils.CalculateCRC(doc.Data);
             return doc;
         }
 
-        private byte[] GetData(string file)
+        private static byte[] GetData(string file)
         {
             Stream stream = new FileStream(file, FileMode.Open, FileAccess.Read, FileShare.Read);
             byte[] pdfData = new byte[stream.Length];
@@ -201,64 +221,49 @@ namespace PRSDesktop
             return pdfData;
         }
 
-        private void LoadExistingStaging()
+        public static void ReloadFile(StagingSetout stagingSetout)
         {
-            CoreTable stagingseouttable = new Client<StagingSetout>().Query(
-                new Filter<StagingSetout>(x => x.Archived).IsEqualTo(DateTime.MinValue),
-                new Columns<StagingSetout>(x => x.Number));
-            var ids = new List<Guid>();
-            foreach (var row in stagingseouttable.Rows)
-                _existingFileNames.Add(row.Get<StagingSetout, string>(x => x.Number));
-        }
+            if (string.IsNullOrWhiteSpace(stagingSetout.SavePath))
+                return;
 
-        private bool CheckSetoutClash(Document document, CancelEventArgs args)
-        {
-            foreach (var existing in _existingFiles)
+            var setoutDocument = new Client<StagingSetoutDocument>()
+                .Query(
+                    new Filter<StagingSetoutDocument>(x => x.EntityLink.ID).IsEqualTo(stagingSetout.ID),
+                    new Columns<StagingSetoutDocument>(x => x.DocumentLink.ID))
+                .ToObjects<StagingSetoutDocument>().FirstOrDefault();
+            if(setoutDocument is null)
             {
-                if (document.FileName.Equals(existing.FileName))
-                {
-                    if(document.CRC != existing.CRC)
-                    {
-                        var result = MessageBox.Show($"A different file with the filename '{document.FileName}' already exists? Do you wish to replace the existing file with the new one?", "Replace Existing", MessageBoxButton.YesNoCancel);
-                        if(result == MessageBoxResult.No)
-                        {
-                            return false;
-                        }
-                        else if(result == MessageBoxResult.Cancel)
-                        {
-                            args.Cancel = true;
-                            return false;
-                        }
-                    }
-                }
-            }
-            return true;
-        }
-
-        public void ReloadFile(StagingSetout stagingSetout)
-        {
-            if (string.IsNullOrWhiteSpace(stagingSetout.SavePath))
+                MessageBox.Show("Could not find the document in the database.");
                 return;
+            }
 
-            CoreTable table = new Client<StagingSetoutDocument>().Query(
-                new Filter<StagingSetoutDocument>(x => x.EntityLink.ID).IsEqualTo(stagingSetout.ID),
-                new Columns<StagingSetoutDocument>(x => x.DocumentLink.ID)
-                );
-            var doc = new Client<Document>().Query(
-                new Filter<Document>(x => x.ID).IsEqualTo(
-                    table.Rows.FirstOrDefault().Get<StagingSetoutDocument, Guid>(x => x.DocumentLink.ID)))
-                .Rows.First()
-                .ToObject<Document>();
-
-            FileInfo file = new FileInfo(stagingSetout.SavePath);
+            var doc = new Client<Document>()
+                .Query(
+                    new Filter<Document>(x => x.ID).IsEqualTo(setoutDocument.DocumentLink.ID),
+                    new Columns<Document>(x => x.ID))
+                .ToObjects<Document>().FirstOrDefault();
+            
             try
             {
-                doc.Data = GetData(stagingSetout.SavePath);
+                var file = new FileInfo(stagingSetout.SavePath);
+                if (doc is null)
+                {
+                    doc = new Document
+                    {
+                        FileName = Path.GetFileName(stagingSetout.SavePath),
+                        Data = GetData(stagingSetout.SavePath)
+                    };
+                    doc.CRC = CoreUtils.CalculateCRC(doc.Data);
+                }
+                else
+                {
+                    doc.Data = GetData(stagingSetout.SavePath);
+                }
                 stagingSetout.SavePath = "";
                 stagingSetout.LockedBy.ID = Guid.Empty;
                 file.Attributes = FileAttributes.Normal;
                 file.Delete();
-                MultiSave save = new MultiSave();
+                var save = new MultiSave();
                 save.Add(typeof(Document), doc);
                 save.Add(typeof(StagingSetout), stagingSetout);
                 save.Save(null, "Reloaded / Unlocked staging setout");