ソースを参照

Added approval logic to staging panel

Kenric Nugteren 1 年間 前
コミット
e50c3f4709

+ 36 - 0
prs.classes/Entities/Staging/Setout/StagingSetout.cs

@@ -1,10 +1,38 @@
 using InABox.Core;
 using System;
 using System.Collections.Generic;
+using System.Linq.Expressions;
 using System.Text;
 
 namespace Comal.Classes
 {
+    public class StagingSetoutPacketsAggregate : CoreAggregate<StagingSetout, StagingManufacturingPacket, Guid>
+    {
+        public override Expression<Func<StagingManufacturingPacket, Guid>> Aggregate => x => x.ID;
+
+        public override AggregateCalculation Calculation => AggregateCalculation.Count;
+
+        public override Dictionary<Expression<Func<StagingManufacturingPacket, object>>, Expression<Func<StagingSetout, object>>> Links =>
+            new Dictionary<Expression<Func<StagingManufacturingPacket, object>>, Expression<Func<StagingSetout, object>>>()
+            {
+                { packet => packet.StagingSetout.ID, setout => setout.ID }
+            };
+    }
+    public class StagingUnapprovedDocumentsAggregate : CoreAggregate<StagingSetout, StagingSetoutDocument, Guid>
+    {
+        public override Expression<Func<StagingSetoutDocument, Guid>> Aggregate => x => x.ID;
+
+        public override AggregateCalculation Calculation => AggregateCalculation.Count;
+
+        public override Filter<StagingSetoutDocument>? Filter => new Filter<StagingSetoutDocument>(x => x.Approved).IsEqualTo(false);
+
+        public override Dictionary<Expression<Func<StagingSetoutDocument, object>>, Expression<Func<StagingSetout, object>>> Links =>
+            new Dictionary<Expression<Func<StagingSetoutDocument, object>>, Expression<Func<StagingSetout, object>>>()
+            {
+                { doc => doc.EntityLink.ID, setout => setout.ID }
+            };
+    }
+
     public class StagingSetout : Entity, IPersistent, IRemotable, ILicense<ManufacturingLicense>
     {
         [TextBoxEditor(Editable = Editable.Disabled)]
@@ -30,6 +58,14 @@ namespace Comal.Classes
         [Caption("Locked By")]
         public EmployeeLink LockedBy { get; set; }
 
+        [IntegerEditor(Editable = Editable.Hidden, Visible = Visible.Optional)]
+        [Aggregate(typeof(StagingSetoutPacketsAggregate))]
+        public int Packets { get; set; }
+
+        [IntegerEditor(Editable = Editable.Hidden, Visible = Visible.Optional)]
+        [Aggregate(typeof(StagingUnapprovedDocumentsAggregate))]
+        public int UnapprovedDocuments { get; set; }
+
         protected override void Init()
         {
             Number = "";

+ 9 - 0
prs.classes/Entities/Staging/Setout/StagingSetoutDocument.cs

@@ -7,5 +7,14 @@ namespace Comal.Classes
 {
     public class StagingSetoutDocument : EntityDocument<StagingSetoutLink>, ILicense<ManufacturingLicense>, IOneToMany<StagingSetout>
     {
+        [CheckBoxEditor]
+        public bool Approved { get; set; }
+
+        protected override void Init()
+        {
+            base.Init();
+
+            Approved = false;
+        }
     }
 }

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

@@ -21,6 +21,8 @@ using System.Drawing.Imaging;
 using net.sf.mpxj.common;
 using System.ComponentModel;
 using com.sun.org.apache.xalan.@internal.xsltc.cmdline.getopt;
+using InABox.WPF;
+using System.Windows.Media.Imaging;
 
 namespace PRSDesktop
 {
@@ -48,6 +50,8 @@ namespace PRSDesktop
 
         public event CustomiseSetoutsEvent? OnCustomiseSetouts;
 
+        private readonly BitmapImage tick = PRSDesktop.Resources.tick.AsBitmapImage();
+
         public StagingSetoutGrid()
         {
             HiddenColumns.Add(x => x.Setout.ID);
@@ -57,9 +61,68 @@ namespace PRSDesktop
             HiddenColumns.Add(x => x.Locked);
             HiddenColumns.Add(x => x.SavePath);
             HiddenColumns.Add(x => x.LockedBy.ID);
+            HiddenColumns.Add(x => x.Packets);
+            HiddenColumns.Add(x => x.UnapprovedDocuments);
+
+            ActionColumns.Add(new DynamicTickColumn<StagingSetout, int>(x => x.Packets, tick, tick, null)
+            {
+                ToolTip = Packets_Tooltip
+            });
+            ActionColumns.Add(new DynamicImageColumn(UnapprovedImage)
+            {
+                ToolTip = Unapproved_Tooltip
+            });
 
             AddButton("Create Group", null, CreateGroup);
         }
+
+        private FrameworkElement? Unapproved_Tooltip(DynamicActionColumn column, CoreRow? row)
+        {
+            if(row is null)
+            {
+                return column.TextToolTip("Approved Documents");
+            }
+            var unapproved = row.Get<StagingSetout, int>(x => x.UnapprovedDocuments);
+            if(unapproved == 0)
+            {
+                return column.TextToolTip("This setout has no unapproved documents");
+            }
+            else
+            {
+                return column.TextToolTip($"This setout has {unapproved} documents");
+            }
+        }
+
+        private FrameworkElement? Packets_Tooltip(DynamicActionColumn column, CoreRow? row)
+        {
+            if (row is null)
+            {
+                return null;
+            }
+            var packets = row.Get<StagingSetout, int>(x => x.Packets);
+            if (packets == 0)
+            {
+                return column.TextToolTip("This setout has no packets");
+            }
+            else
+            {
+                return column.TextToolTip($"This setout has {packets} packets");
+            }
+        }
+
+        private BitmapImage? UnapprovedImage(CoreRow? arg)
+        {
+            if(arg is null)
+            {
+                return null;
+            }
+            if(arg.Get<StagingSetout, int>(x => x.UnapprovedDocuments) == 0)
+            {
+                return tick;
+            }
+            return null;
+        }
+
         protected override void DoReconfigure(FluentList<DynamicGridOption> options)
         {
             base.DoReconfigure(options);

+ 8 - 3
prs.desktop/Panels/Staging/StagingPanel.xaml

@@ -65,6 +65,11 @@
                                             x:Name="RejectButton"
                                             Click="RejectButton_Click"
                                             IsEnabled="False"/>
+                                    <Button DockPanel.Dock="Right"
+                                            Content="Approve"
+                                            x:Name="ApproveButton"
+                                            Height="35" Padding="20,5" Margin="5"
+                                            Click="ApproveButton_Click"/>
                                 </DockPanel>
                             </Border>
                         </Grid>
@@ -103,10 +108,10 @@
                             <DockPanel LastChildFill="False"
                                        Grid.Row="1">
                                 <Button DockPanel.Dock="Right"
-                                        Content="Approve"
-                                        x:Name="ApproveButton"
+                                        Content="Process"
+                                        x:Name="ProcessButton"
                                         Height="35" Padding="20,5" Margin="5"
-                                        Click="ApproveButton_Click"/>
+                                        Click="ProcessButton_Click"/>
                             </DockPanel>
                         </Grid>
                     </Border>

+ 54 - 7
prs.desktop/Panels/Staging/StagingPanel.xaml.cs

@@ -140,6 +140,7 @@ public class Module
             MarkUpButton.Visibility = Security.IsAllowed<CanMarkUpSetouts>() ? Visibility.Visible : Visibility.Hidden;
             RejectButton.Visibility = Security.IsAllowed<CanApproveSetouts>() ? Visibility.Visible : Visibility.Hidden;
             ApproveButton.Visibility = Security.IsAllowed<CanApproveSetouts>() ? Visibility.Visible : Visibility.Hidden;
+            ProcessButton.Visibility = Security.IsAllowed<CanApproveSetouts>() ? Visibility.Visible : Visibility.Hidden;
 
             //stagingSetoutGrid.ScanFiles(_settings.SetoutsFolder);
             stagingSetoutGrid.Refresh(true, true);
@@ -172,23 +173,26 @@ public class Module
                 if (_mode == DocumentMode.Markup)
                 {
                     MarkUpButton.Content = "Mark Up";
-                    MarkUpButton.IsEnabled = Document != null;
+                    MarkUpButton.IsEnabled = Document != null && !Document.Approved;
+                    ProcessButton.IsEnabled = Document != null && Document.Approved;
+                    RejectButton.IsEnabled = Document != null && !Document.Approved;
                     ApproveButton.IsEnabled = Document != null;
-                    RejectButton.IsEnabled = Document != null;
                 }
                 else if (_mode == DocumentMode.Complete)
                 {
                     MarkUpButton.Content = "Complete";
                     MarkUpButton.IsEnabled = Document != null;
-                    ApproveButton.IsEnabled = false;
+                    ProcessButton.IsEnabled = false;
                     RejectButton.IsEnabled = false;
+                    ApproveButton.IsEnabled = false;
                 }
                 else if (_mode == DocumentMode.Locked)
                 {
                     MarkUpButton.Content = "Locked";
                     MarkUpButton.IsEnabled = false;
-                    ApproveButton.IsEnabled = false;
+                    ProcessButton.IsEnabled = false;
                     RejectButton.IsEnabled = false;
+                    ApproveButton.IsEnabled = false;
                 }
             }
         }
@@ -233,7 +237,7 @@ public class Module
             }
         }
 
-        private void ApproveButton_Click(object sender, RoutedEventArgs e)
+        private void ProcessButton_Click(object sender, RoutedEventArgs e)
         {
             bool bulkApprove = false;
             if (selectedSetouts.Count > 1)
@@ -244,6 +248,20 @@ public class Module
                     Progress.Show("Approving Setouts..");
                 }
             }
+            if(selectedSetouts.Any(x => x.UnapprovedDocuments > 0))
+            {
+                MessageBox.Show("Cannot process setouts with unapproved documents.");
+                Progress.Close();
+                return;
+            }
+            else if(selectedSetouts.Any(x => x.Packets == 0))
+            {
+                if(MessageBox.Show("Warning: some setouts do not have any manufacturing packets: are you sure you wish to proceed?", "Warning", MessageBoxButton.YesNoCancel) != MessageBoxResult.Yes)
+                {
+                    Progress.Close();
+                    return;
+                }
+            }
 
             string message = "Result: " + Environment.NewLine;
 
@@ -372,7 +390,20 @@ public class Module
             }
 
             var packets = new List<Tuple<ManufacturingPacket, StagingManufacturingPacket>>();
-            foreach(var stagingPacket in ManufacturingPacketList.GetPackets())
+            var stagingPackets = new Client<StagingManufacturingPacket>()
+                .Query(
+                    new Filter<StagingManufacturingPacket>(x => x.StagingSetout.ID).IsEqualTo(item.ID),
+                    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.ID)
+                        .Add(x => x.Location)
+                        .Add(x => x.ITP.ID)
+                        .Add(x => x.Job.ID)
+                        .Add(x => x.Template.ID));
+            foreach(var stagingPacket in stagingPackets.ToObjects<StagingManufacturingPacket>())
             {
                 if(stagingPacket.ManufacturingPacket.ID != Guid.Empty)
                 {
@@ -491,6 +522,18 @@ public class Module
             }
         }
 
+        private void ApproveButton_Click(object sender, RoutedEventArgs e)
+        {
+            if (Document is null || selectedSetout is null)
+            {
+                MessageBox.Show("Please select a setout first.");
+                return;
+            }
+            Document.Approved = !Document.Approved;
+            new Client<StagingSetoutDocument>().Save(Document, "");
+            stagingSetoutGrid.Refresh(false, true);
+        }
+
         private void OnMarkupSelected()
         {
             if (Document is null || selectedSetout is null)
@@ -561,12 +604,14 @@ public class Module
             var doc = new Client<StagingSetoutDocument>()
                 .Query(
                     new Filter<StagingSetoutDocument>(x => x.EntityLink.ID).IsEqualTo(selectedSetout.ID),
-                    new Columns<StagingSetoutDocument>(x => x.ID, x => x.DocumentLink.ID, x => x.DocumentLink.FileName))
+                    new Columns<StagingSetoutDocument>(x => x.ID, x => x.DocumentLink.ID, x => x.DocumentLink.FileName, x => x.Approved))
                 .ToObjects<StagingSetoutDocument>().FirstOrDefault();
             if(doc is null)
             {
                 MessageBox.Show("No document found for this setout.");
                 Document = null;
+                ManufacturingPacketList.Setout = null;
+                CollapsePacketsButton.IsEnabled = false;
                 return;
             }
 
@@ -582,6 +627,7 @@ public class Module
                     selectedSetout.LockedBy.ID == App.EmployeeID ?
                         DocumentMode.Complete :
                         DocumentMode.Locked;
+            ApproveButton.Content = Document.Approved ? "Unapprove" : "Approve";
         }
 
         public bool IsReady { get; set; }
@@ -682,6 +728,7 @@ public class Module
         private void AddPacketButton_Click(object sender, RoutedEventArgs e)
         {
             ManufacturingPacketList.Add();
+            stagingSetoutGrid.Refresh(false, true);
         }
 
         private void CollapsePacketsButton_Click(object sender, RoutedEventArgs e)