Selaa lähdekoodia

Added ability to copy packets from one setout to another on staging grid.

Kenric Nugteren 1 vuosi sitten
vanhempi
commit
4fa0faebfe

+ 55 - 47
prs.desktop/Panels/Staging/Manufacturing/StagingManufacturingPacketList.xaml.cs

@@ -44,43 +44,7 @@ namespace PRSDesktop
                     return;
                 }
                 _setout = value;
-                if(value is null)
-                {
-                    ManufacturingPacketList.Children.Clear();
-                }
-                else
-                {
-                    var results = Client.QueryMultiple(StagingManufacturingPacketListItem.GetQueries(value));
-                    /*var results = Client.Query(
-                        new Filter<StagingManufacturingPacket>(x => x.StagingSetout.ID).IsEqualTo(value.ID),
-                        DynamicGridUtils.LoadEditorColumns(
-                            new Columns<StagingManufacturingPacket>(x => x.ID)
-                                .Add(x => x.Serial)
-                                .Add(x => x.Title)
-                                .Add(x => x.Quantity)
-                                .Add(x => x.BarcodeQuantity)
-                                .Add(x => x.Watermark)
-                                .Add(x => x.Location)
-                                .Add(x => x.ITP.ID)
-                                .Add(x => x.ITP.Code)
-                                .Add(x => x.ITP.Description)
-                                .Add(x => x.Job.ID)
-                                .Add(x => x.Group.ID)
-                                .Add(x => x.Group.Code)
-                                .Add(x => x.Group.Description)
-                                .Add(x => x.Group.Watermark)
-                                .Add(x => x.Template.ID)
-                                .Add(x => x.Template.Code)
-                                .Add(x => x.ManufacturingPacket.ID)));*/
-
-                    ManufacturingPacketList.Children.Clear();
-                    foreach(var packet in results.GetObjects<StagingManufacturingPacket>())
-                    {
-                        AddItem(packet, results);
-                    }
-                    OnCollapsed?.Invoke(Collapsed());
-                }
-                Changed?.Invoke(this, EventArgs.Empty);
+                Refresh();
             }
         }
         
@@ -98,6 +62,47 @@ namespace PRSDesktop
             InitializeComponent();
         }
 
+        public void Refresh()
+        {
+            if (Setout is null)
+            {
+                ManufacturingPacketList.Children.Clear();
+            }
+            else
+            {
+                var results = Client.QueryMultiple(StagingManufacturingPacketListItem.GetQueries(Setout));
+                /*var results = Client.Query(
+                    new Filter<StagingManufacturingPacket>(x => x.StagingSetout.ID).IsEqualTo(value.ID),
+                    DynamicGridUtils.LoadEditorColumns(
+                        new Columns<StagingManufacturingPacket>(x => x.ID)
+                            .Add(x => x.Serial)
+                            .Add(x => x.Title)
+                            .Add(x => x.Quantity)
+                            .Add(x => x.BarcodeQuantity)
+                            .Add(x => x.Watermark)
+                            .Add(x => x.Location)
+                            .Add(x => x.ITP.ID)
+                            .Add(x => x.ITP.Code)
+                            .Add(x => x.ITP.Description)
+                            .Add(x => x.Job.ID)
+                            .Add(x => x.Group.ID)
+                            .Add(x => x.Group.Code)
+                            .Add(x => x.Group.Description)
+                            .Add(x => x.Group.Watermark)
+                            .Add(x => x.Template.ID)
+                            .Add(x => x.Template.Code)
+                            .Add(x => x.ManufacturingPacket.ID)));*/
+
+                ManufacturingPacketList.Children.Clear();
+                foreach (var packet in results.GetObjects<StagingManufacturingPacket>())
+                {
+                    AddItem(packet, results);
+                }
+                OnCollapsed?.Invoke(Collapsed());
+            }
+            Changed?.Invoke(this, EventArgs.Empty);
+        }
+
         public IEnumerable<StagingManufacturingPacket> GetPackets()
         {
             return ManufacturingPacketList.Children.Cast<StagingManufacturingPacketListItem>()
@@ -127,6 +132,18 @@ namespace PRSDesktop
             Changed?.Invoke(this, EventArgs.Empty);
         }
 
+        public static string GenerateSerialNumber(StagingSetout setout, string? groupCode, IEnumerable<StagingManufacturingPacket> packets)
+        {
+            string serialbase = $"{setout.Number}-";
+            if (!groupCode.IsNullOrWhiteSpace())
+                serialbase = $"{serialbase}{groupCode}-";
+            var pkts = packets.Where(x => x.Serial.StartsWith(serialbase)).ToArray();
+            int iSerial = 1;
+            while (pkts.Any(x => String.Equals(x.Serial, $"{serialbase}{iSerial:D3}")))
+                iSerial++;
+            return $"{serialbase}{iSerial:D3}";
+        }
+
         public void Add(Guid jobid, IManufacturingTemplateGroup? group)
         {
             if (Setout is null)
@@ -159,16 +176,7 @@ namespace PRSDesktop
             }
 
             newPacket.StagingSetout.ID = Setout.ID;
-
-
-            string serialbase = $"{Setout.Number}-";
-            if (group != null)
-                serialbase = $"{serialbase}{group.Code}-";
-            var pkts = GetPackets().Where(x => x.Serial.StartsWith(serialbase)).ToArray();
-            int iSerial = 1;
-            while (pkts.Any(x => String.Equals(x.Serial, $"{serialbase}{iSerial:D3}")))
-                iSerial++;
-            newPacket.Serial = $"{serialbase}{iSerial:D3}";
+            newPacket.Serial = GenerateSerialNumber(Setout, group?.Code, GetPackets());
             
             new Client<StagingManufacturingPacket>().Save(newPacket,"Created from Staging Panel");
 

+ 183 - 0
prs.desktop/Panels/Staging/Setouts/StagingSetoutGrid.cs

@@ -24,6 +24,7 @@ using InABox.WPF;
 using System.Windows.Media.Imaging;
 using InABox.Configuration;
 using NPOI.HSSF.Util;
+using System.Reactive.Linq;
 
 namespace PRSDesktop
 {
@@ -80,6 +81,9 @@ namespace PRSDesktop
         public delegate void ParseComponentFile(string componentFileName, Guid setoutID);
         public event ParseComponentFile? OnParseComponentFile;
 
+        public delegate void RefreshPacketsEvent();
+        public event RefreshPacketsEvent? OnRefreshPackets;
+
         private readonly BitmapImage locked = PRSDesktop.Resources.locked.AsBitmapImage();
         private readonly BitmapImage revision = PRSDesktop.Resources.revision.AsBitmapImage();
         private readonly BitmapImage docs = PRSDesktop.Resources.design.AsBitmapImage();
@@ -88,6 +92,10 @@ namespace PRSDesktop
         private readonly BitmapImage warning = PRSDesktop.Resources.warning.AsBitmapImage();
         private readonly BitmapImage rejected = PRSDesktop.Resources.disabled.AsBitmapImage();
 
+        private Button CopyPacketsButton;
+        private Button PastePacketsButton;
+        private StagingSetout? CopyPacketsSource;
+
         public StagingSetoutGrid()
         {
             HiddenColumns.Add(x => x.Setout.ID);
@@ -131,6 +139,181 @@ namespace PRSDesktop
             ActionColumns.Add(new DynamicMenuColumn(Menu_Build));
             
             AddButton("Create Group", null, CreateGroup);
+
+            CopyPacketsButton = AddButton("Copy Packets", PRSDesktop.Resources.copy.AsBitmapImage(), CopyPackets);
+            PastePacketsButton = AddButton("Paste Packets", InABox.Wpf.Resources.paste.AsBitmapImage(), PastePackets);
+            PastePacketsButton.Visibility = Visibility.Collapsed;
+        }
+
+        protected override void SelectItems(CoreRow[]? rows)
+        {
+            base.SelectItems(rows);
+
+            if(CopyPacketsSource is null)
+            {
+                CopyPacketsButton.IsEnabled = rows?.Length == 1;
+                PastePacketsButton.IsEnabled = false;
+            }
+            else
+            {
+                CopyPacketsButton.IsEnabled = false;
+                PastePacketsButton.IsEnabled = rows is not null && rows.Length > 0
+                    && !rows.Any(x => x.Get<StagingSetout, Guid>(x => x.ID) == CopyPacketsSource.ID);
+            }
+        }
+
+        private bool PastePackets(Button button, CoreRow[] rows)
+        {
+            if(CopyPacketsSource is null)
+            {
+                MessageBox.Show("Please first select a setout to copy from.");
+                return false;
+            }
+            else if (rows.Length == 0)
+            {
+                MessageBox.Show("Please select at least one setout to copy packets to.");
+                return false;
+            }
+            else if(rows.Any(x => x.Get<StagingSetout, Guid>(x => x.ID) == CopyPacketsSource.ID))
+            {
+                MessageBox.Show("Cannot copy packets from a setout to itself.");
+                return false;
+            }
+
+            var packetFilter = new Filter<StagingManufacturingPacket>(x => x.StagingSetout.ID).IsEqualTo(CopyPacketsSource.ID);
+
+            var results = Client.QueryMultiple(
+                new KeyedQueryDef<StagingManufacturingPacket>(
+                    packetFilter,
+                    new Columns<StagingManufacturingPacket>(x => x.ID)
+                        .Add(x => x.Title)
+                        .Add(x => x.Job.ID)
+                        .Add(x => x.ITP.ID)
+                        .Add(x => x.Watermark)
+                        .Add(x => x.Location)
+                        .Add(x => x.Quantity)
+                        .Add(x => x.BarcodeQuantity)
+                        .Add(x => x.Group.ID)
+                        .Add(x => x.Group.Code)
+                        .Add(x => x.Template.ID)),
+                new KeyedQueryDef<StagingManufacturingPacketStage>(
+                    new Filter<StagingManufacturingPacketStage>(x => x.Packet.ID).InQuery(packetFilter, x => x.ID),
+                    new Columns<StagingManufacturingPacketStage>(x => x.Packet.ID)
+                        .Add(x => x.Section.ID)
+                        .Add(x => x.Time)
+                        .Add(x => x.SequenceType)
+                        .Add(x => x.Sequence)
+                        .Add(x => x.QualityChecks)),
+                new KeyedQueryDef<StagingManufacturingPacketTreatment>(
+                    new Filter<StagingManufacturingPacketTreatment>(x => x.Packet.ID).InQuery(packetFilter, x => x.ID),
+                    new Columns<StagingManufacturingPacketTreatment>(x => x.Packet.ID)
+                        .Add(x => x.Product.ID)
+                        .Add(x => x.Parameter)));
+
+            var stages = results.GetObjects<StagingManufacturingPacketStage>()
+                .GroupBy(x => x.Packet.ID)
+                .ToDictionary(x => x.Key, x => x.ToList());
+
+            var treatments = results.GetObjects<StagingManufacturingPacketTreatment>()
+                .GroupBy(x => x.Packet.ID)
+                .ToDictionary(x => x.Key, x => x.ToList());
+
+            var targets = rows.Select(x => x.ToObject<StagingSetout>()).ToList();
+
+            var currentPackets = Client.Query(
+                new Filter<StagingManufacturingPacket>(x => x.StagingSetout.ID).InList(targets.Select(x => x.ID).ToArray()),
+                new Columns<StagingManufacturingPacket>(x => x.StagingSetout.ID).Add(x => x.Serial))
+                .ToObjects<StagingManufacturingPacket>();
+
+            var newPackets = new List<(StagingManufacturingPacket originalPacket, StagingManufacturingPacket newPacket)>();
+            foreach(var target in targets)
+            {
+                foreach (var originalPacket in results.GetObjects<StagingManufacturingPacket>())
+                {
+                    var newPacket = new StagingManufacturingPacket
+                    {
+                        Title = originalPacket.Title,
+                        Watermark = originalPacket.Watermark,
+                        Location = originalPacket.Location,
+                        Quantity = originalPacket.Quantity,
+                        BarcodeQuantity = originalPacket.BarcodeQuantity
+                    };
+                    newPacket.Group.ID = originalPacket.Group.ID;
+                    newPacket.Template.ID = originalPacket.Template.ID;
+                    if(originalPacket.Job.ID == target.JobLink.ID)
+                    {
+                        newPacket.Job.ID = originalPacket.Job.ID;
+                        newPacket.ITP.ID = originalPacket.ITP.ID;
+                    }
+                    newPacket.Serial = StagingManufacturingPacketList.GenerateSerialNumber(target, originalPacket.Group.Code,
+                        Enumerable.Concat(newPackets.Select(x => x.newPacket), currentPackets.Where(x => x.StagingSetout.ID == target.ID)));
+                    newPacket.StagingSetout.ID = target.ID;
+                    newPackets.Add((originalPacket, newPacket));
+                }
+            }
+            Client.Save(newPackets.Select(x => x.newPacket), $"Copied from setout '{CopyPacketsSource.Number}'");
+
+            var newStages = new List<StagingManufacturingPacketStage>();
+            var newTreatments = new List<StagingManufacturingPacketTreatment>();
+
+            foreach(var (originalPacket, newPacket) in newPackets)
+            {
+                if(stages.TryGetValue(originalPacket.ID, out var originalStages))
+                {
+                    foreach(var originalStage in originalStages)
+                    {
+                        var newStage = new StagingManufacturingPacketStage();
+                        newStage.Packet.ID = newPacket.ID;
+                        newStage.Section.ID = originalStage.Section.ID;
+                        newStage.Time = originalStage.Time;
+                        newStage.SequenceType = originalStage.SequenceType;
+                        newStage.Sequence = originalStage.Sequence;
+                        newStage.QualityChecks = originalStage.QualityChecks;
+                        newStages.Add(newStage);
+                    }
+                }
+                if (treatments.TryGetValue(originalPacket.ID, out var originalTreatments))
+                {
+                    foreach (var originalTreatment in originalTreatments)
+                    {
+                        var newTreatment = new StagingManufacturingPacketTreatment();
+                        newTreatment.Packet.ID = newPacket.ID;
+                        newTreatment.Product.ID = originalTreatment.Product.ID;
+                        newTreatment.Parameter = originalTreatment.Parameter;
+                        newTreatments.Add(newTreatment);
+                    }
+                }
+            }
+
+            Client.Save(newStages, $"Copied from setout '{CopyPacketsSource.Number}'");
+            Client.Save(newTreatments, $"Copied from setout '{CopyPacketsSource.Number}'");
+
+            CopyPacketsSource = null;
+            CopyPacketsButton.Visibility = Visibility.Visible;
+            PastePacketsButton.Visibility = Visibility.Collapsed;
+
+            OnRefreshPackets?.Invoke();
+            return false;
+        }
+
+        private bool CopyPackets(Button button, CoreRow[] rows)
+        {
+            if (rows.Length == 0)
+            {
+                MessageBox.Show("Please select a setout to copy packets from.");
+                return false;
+            }
+            else if (rows.Length != 1)
+            {
+                MessageBox.Show("Cannot copy packets from more than one setout.");
+                return false;
+            }
+
+            CopyPacketsSource = rows.First().ToObject<StagingSetout>();
+            CopyPacketsButton.Visibility = Visibility.Collapsed;
+            PastePacketsButton.Visibility = Visibility.Visible;
+
+            return false;
         }
 
         private void Menu_Build(DynamicMenuColumn column, CoreRow? row)

+ 1 - 0
prs.desktop/Panels/Staging/StagingPanel.xaml

@@ -30,6 +30,7 @@
                     OnParseComponentFile="stagingSetoutGrid_OnParseComponentFile"
                     OnDoubleClick="StagingSetoutGrid_OnOnDoubleClick"
                     AfterRefresh="stagingSetoutGrid_AfterRefresh"
+                    OnRefreshPackets="stagingSetoutGrid_OnRefreshPackets"
                     OnSelectItem="StagingSetoutGrid_OnSelectItem"/>
             </Grid>
         </dynamicgrid:DynamicSplitPanel.Master>

+ 8 - 0
prs.desktop/Panels/Staging/StagingPanel.xaml.cs

@@ -928,6 +928,14 @@ public class Module
             CalculateTime();
         }
 
+        private void stagingSetoutGrid_OnRefreshPackets()
+        {
+            if (CanViewPackets())
+            {
+                ManufacturingPacketList.Refresh();
+            }
+        }
+
         public Dictionary<string, object[]> Selected()
         {
             return new();