Sfoglia il codice sorgente

Merge remote-tracking branch 'origin/requisition_changes' into frank

frogsoftware 1 anno fa
parent
commit
86db19e04c

+ 4 - 1
prs.classes/Entities/Requisition/RequisitionItem.cs

@@ -50,10 +50,13 @@ namespace Comal.Classes
         public double Quantity { get; set; }
 
         [EditorSequence(8)]
+        public double ActualQuantity { get; set; }
+
+        [EditorSequence(9)]
         [RequiredColumn]
         public StockLocationLink Location { get; set; }
 
-        [EditorSequence(9)]
+        [EditorSequence(10)]
         [TimestampEditor]
         public DateTime Picked { get; set; }
         

+ 1 - 1
prs.desktop/Panels/Products/Locations/StockHoldingGrid.cs

@@ -558,7 +558,7 @@ namespace PRSDesktop
             // Hackety Hackety Hack Hack stupid doubles not totalling zero when they're supposed to
             var result = base.FilterRecord(row);
             if (result)
-                result = !row.Get<StockHolding, double>(x => x.Qty).ToString("F8").Equals("0.00000000");
+                result = Math.Abs(row.Get<StockHolding, double>(x => x.Qty)) >= 0.000001;
             return result;
         }
     }

+ 0 - 64
prs.desktop/Panels/Requisitions/RequisitionGrid.cs

@@ -19,8 +19,6 @@ namespace PRSDesktop
         //public Dictionary<Object, Object> _Employees = new Dictionary<object, object>();
         //public Dictionary<Object, Object> _Jobs = new Dictionary<object, object>();
 
-
-        private readonly ComboBox _filter;
         private readonly BitmapImage barcode = PRSDesktop.Resources.barcode.AsBitmapImage();
 
         private bool bSplitting;
@@ -33,54 +31,6 @@ namespace PRSDesktop
 
         public RequisitionGrid()
         {
-            var left = new Border
-            {
-                Height = 30,
-                Width = 30,
-                Margin = new Thickness(0, 0, 2, 2),
-                BorderBrush = new SolidColorBrush(Colors.Gray),
-                BorderThickness = new Thickness(0.75),
-                Background = new SolidColorBrush(Colors.WhiteSmoke),
-                CornerRadius = new CornerRadius(5, 0, 0, 0)
-            };
-            left.SetValue(DockPanel.DockProperty, Dock.Left);
-
-            var right = new Border
-            {
-                Height = 30,
-                Width = 30,
-                Margin = new Thickness(2, 0, 0, 2),
-                BorderBrush = new SolidColorBrush(Colors.Gray),
-                BorderThickness = new Thickness(0.75),
-                Background = new SolidColorBrush(Colors.WhiteSmoke),
-                CornerRadius = new CornerRadius(0, 5, 0, 0)
-            };
-            right.SetValue(DockPanel.DockProperty, Dock.Right);
-
-            _filter = new ComboBox
-            {
-                ItemsSource = new List<string>
-                {
-                    "All Requisitions",
-                    "Unfilled Requisitions",
-                    "Requisitions needing Delivery",
-                    "Requisitions to be Archived"
-                },
-                Margin = new Thickness(0, 0, 0, 2),
-                VerticalContentAlignment = VerticalAlignment.Center,
-                HorizontalContentAlignment = HorizontalAlignment.Center,
-                SelectedIndex = 2,
-                Height = 30
-            };
-            _filter.SetValue(DockPanel.DockProperty, Dock.Left);
-            _filter.SelectionChanged += (o, e) => Refresh(false, true);
-
-            var header = new DockPanel();
-            header.Children.Add(left);
-            header.Children.Add(right);
-            header.Children.Add(_filter);
-            Header = header;
-
             ActionColumns.Add(new DynamicImageColumn(DocumentsImage, DocumentsClick) { Position = DynamicActionColumnPosition.Start });
             ActionColumns.Add(new DynamicImageColumn(FilledImage));
             ActionColumns.Add(new DynamicImageColumn(DeliveryImage));
@@ -409,20 +359,6 @@ namespace PRSDesktop
         protected override void Reload(Filters<Requisition> criteria, Columns<Requisition> columns, ref SortOrder<Requisition>? sort,
             Action<CoreTable?, Exception?> action)
         {
-            // Unfilled
-            if (_filter.SelectedIndex == 1)
-                criteria.Add(new Filter<Requisition>(x => x.Filled).IsEqualTo(DateTime.MinValue));
-
-            // Undelivered
-            else if (_filter.SelectedIndex == 2)
-                criteria.Add(new Filter<Requisition>(x => x.Archived).IsEqualTo(DateTime.MinValue).Or(x => x.Filled).IsEqualTo(DateTime.MinValue));
-
-            // Unarchived
-            else if (_filter.SelectedIndex == 3)
-                criteria.Add(new Filter<Requisition>(x => x.StockUpdated).IsEqualTo(DateTime.MinValue).Or(x => x.Archived)
-                    .IsEqualTo(DateTime.MinValue)
-                    .Or(x => x.Filled).IsEqualTo(DateTime.MinValue));
-
             sort = new SortOrder<Requisition>(x => x.Number, SortDirection.Descending);
 
             base.Reload(criteria, columns, ref sort, action);

+ 96 - 23
prs.desktop/Panels/Requisitions/RequisitionItemGrid.cs

@@ -2,10 +2,13 @@
 using System.Collections.Generic;
 using System.Linq;
 using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Media.Imaging;
 using Comal.Classes;
 using InABox.Clients;
 using InABox.Core;
 using InABox.DynamicGrid;
+using InABox.Wpf;
 using InABox.WPF;
 using Microsoft.Office.Interop.Outlook;
 using Syncfusion.Windows.Tools.Controls;
@@ -17,7 +20,7 @@ namespace PRSDesktop
     {
         //public int Boxes { get; set; }
 
-        public bool Picked = true;
+        private static readonly BitmapImage tick = PRSDesktop.Resources.tick.AsBitmapImage();
 
         public RequisitionItemGrid()
         {
@@ -54,12 +57,94 @@ namespace PRSDesktop
             HiddenColumns.Add(x => x.Style.ID);
             HiddenColumns.Add(x => x.Style.Code);
             HiddenColumns.Add(x => x.Picked);
+            ActionColumns.Add(new DynamicImageColumn(Pick_Image, Pick_Click)
+            {
+                ToolTip = Pick_ToolTip
+            });
             ActionColumns.Add(new DynamicMenuColumn(SelectHolding,
                 (row) => (row.Get<RequisitionItem, Guid>(c => c.Product.ID) == Guid.Empty) || row.Get<RequisitionItem, bool>(c => c.Product.NonStock) == true
                     ? DynamicMenuStatus.Hidden
                     : DynamicMenuStatus.Enabled)
             );
         }
+
+        private FrameworkElement? Pick_ToolTip(DynamicActionColumn column, CoreRow? row)
+        {
+            string content;
+            if (row is null)
+            {
+                content = "Has this item been picked?";
+            }
+            else
+            {
+                if(!row.Get<RequisitionItem, DateTime>(x => x.Picked).IsEmpty())
+                {
+                    content = "This item has been picked";
+                }
+                else
+                {
+                    content = "This item has not been picked";
+                }
+            }
+            return column.TextToolTip(content);
+        }
+
+        private BitmapImage? Pick_Image(CoreRow? row)
+        {
+            return row is null
+                ? tick
+                : (row.Get<RequisitionItem, DateTime>(x => x.Picked).IsEmpty()
+                    ? null
+                    : tick);
+        }
+
+        private bool Pick_Click(CoreRow? row)
+        {
+            if(row is null)
+            {
+                return false;
+            }
+
+            var reqItem = row.ToObject<RequisitionItem>();
+            return ProcessItems(reqItem.Picked.IsEmpty() ? DateTime.Now : DateTime.MinValue, CoreUtils.One(reqItem));
+        }
+
+        private static bool ProcessItems(DateTime picked, IEnumerable<RequisitionItem> items)
+        {
+            var list = new List<RequisitionItem>();
+            foreach (var item in items)
+            {
+                item.Picked = picked;
+
+                if (!picked.IsEmpty())
+                {
+                    var quantity = item.Quantity;
+                    if (!DoubleEdit.Execute("Enter actual quantity picked:", 0, double.MaxValue, ref quantity))
+                    {
+                        continue;
+                    }
+                    item.ActualQuantity = quantity;
+                }
+
+                list.Add(item);
+            }
+
+            if(list.Count > 0)
+            {
+                string audittrail;
+                if (picked == DateTime.MinValue)
+                    audittrail = "Item unpicked";
+                else
+                    audittrail = "Item picked " + picked.ToString("dd MMM yy");
+                Client.Save(list, audittrail);
+                return true;
+            }
+            else
+            {
+                return false;
+            }
+        }
+
         protected override void DoReconfigure(FluentList<DynamicGridOption> options)
         {
             base.DoReconfigure(options);
@@ -75,14 +160,6 @@ namespace PRSDesktop
                 .EndUpdate();
         }
 
-        protected override void DoBeforeSave(IDynamicEditorForm editor, RequisitionItem[] items)
-        {
-            base.DoBeforeSave(editor, items);
-
-            foreach (var item in items)
-                item.Picked = Picked ? DateTime.Now : DateTime.MinValue;
-        }
-
         private bool CanAddItems() =>
             Requisition is not null && Requisition.ID != Guid.Empty && Requisition.Filled.IsEmpty() && Security.CanEdit<Requisition>() && Security.CanEdit<RequisitionItem>();
 
@@ -119,7 +196,7 @@ namespace PRSDesktop
                             item.Product.ID = product.ID;
                             item.Product.Synchronise(product);
                             item.Quantity = quantity;
-                            item.Picked = Picked ? DateTime.Now : DateTime.MinValue;
+                            item.Picked = DateTime.MinValue;
                             SaveItem(item);
                             Refresh(false, true);
                         }
@@ -130,8 +207,13 @@ namespace PRSDesktop
 
         private void SelectHolding(DynamicMenuColumn column, CoreRow? row)
         {
-            List<Guid> locations = new List<Guid>();
-            var holdings = new Client<StockHolding>().Query(
+            if(row is null)
+            {
+                return;
+            }
+
+            var locations = new List<Guid>();
+            var holdings = Client.Query(
                 new Filter<StockHolding>(x => x.Product.ID).IsEqualTo(row.Get<RequisitionItem, Guid>(c => c.Product.ID)),
                 new Columns<StockHolding>(x => x.Location.ID)
                     .Add(x => x.Units));
@@ -145,7 +227,7 @@ namespace PRSDesktop
 
             if (locations.Count == 0)
             {
-                MessageBox.Show("No valid holdings found for product");
+                MessageWindow.ShowMessage("No valid holdings found for product", "No holdings");
                 return;
             }
 
@@ -210,22 +292,13 @@ namespace PRSDesktop
             criteria.Add(
                 new Filter<RequisitionItem>(x => x.RequisitionLink.ID).IsEqualTo(Requisition != null ? Requisition.ID : CoreUtils.FullGuid));
 
-            if (Picked)
-                criteria.Add(new Filter<RequisitionItem>(x => x.Picked).IsNotEqualTo(DateTime.MinValue));
-            else
-                criteria.Add(new Filter<RequisitionItem>(x => x.Picked).IsEqualTo(DateTime.MinValue));
-
             sort = new SortOrder<RequisitionItem>(x => x.Created);
 
             base.Reload(
                 criteria,
                 columns,
                 ref sort,
-                (o, e) =>
-                {
-                    // Update Buttons Here
-                    action.Invoke(o, e);
-                }
+                action
             );
         }
 

+ 125 - 150
prs.desktop/Panels/Requisitions/RequisitionPanel.xaml

@@ -5,163 +5,138 @@
              xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
              xmlns:local="clr-namespace:PRSDesktop"
              xmlns:syncfusion="http://schemas.syncfusion.com/wpf"
+             xmlns:dg="clr-namespace:InABox.DynamicGrid;assembly=InABox.Wpf"
              mc:Ignorable="d"
              d:DesignHeight="800" d:DesignWidth="1500">
-    <Grid x:Name="Grid">
-        <Grid.ColumnDefinitions>
-            <ColumnDefinition Width="450" />
-            <ColumnDefinition Width="Auto" />
-            <ColumnDefinition Width="*" />
-            <ColumnDefinition Width="Auto" />
-            <ColumnDefinition Width="*" />
-            <ColumnDefinition Width="450" />
-        </Grid.ColumnDefinitions>
-        <Grid.RowDefinitions>
-            <RowDefinition Height="32" />
-            <RowDefinition Height="*" />
-        </Grid.RowDefinitions>
-
-
-        <local:RequisitionGrid x:Name="Requisitions" Grid.Row="0" Grid.Column="0" Grid.RowSpan="2"
-                               OnSelectItem="Requisitions_OnSelectItem" />
-
-        <syncfusion:SfGridSplitter Grid.Row="0" Grid.Column="1" Grid.RowSpan="2" Name="Splitter"
-                                   VerticalAlignment="Stretch" ResizeBehavior="PreviousAndNext" Width="Auto"
-                                   Background="WhiteSmoke" />
-       
-        <Border Grid.Row="0" Grid.Column="2" Margin="0,0,0,2" BorderBrush="Gray" BorderThickness="0.75"
-                CornerRadius="5,5,0,0" Background="WhiteSmoke">
-            <Label Content="Requested Items" VerticalContentAlignment="Center"
-                   HorizontalContentAlignment="Center" />
-        </Border>
-        <local:RequisitionItemGrid x:Name="UnPickedItems" Grid.Row="1" Grid.Column="2" />
-
-        <Grid Grid.Row="1" Grid.Column="3" HorizontalAlignment="Center" VerticalAlignment="Center">
-            <Grid.RowDefinitions>
-                <RowDefinition Height="auto"/>
-                <RowDefinition Height="auto"/>
-                <RowDefinition Height="500"/>
-            </Grid.RowDefinitions>
-            <Button Grid.Row="0" Margin="2,2,2,5" Click="PickItems_Click">
-                <Image Source="pack://application:,,,/Resources/rightarrow.png"/>
-            </Button>
-            <Button Grid.Row="1" Margin="2,5,2,2" Click="UnPickItems_Click">
-                <Image Source="pack://application:,,,/Resources/leftarrow.png"/>
-            </Button>
-               
-        </Grid>
-
-        <Border Grid.Row="0" Grid.Column="4" Margin="0,0,0,2" BorderBrush="Gray" BorderThickness="0.75"
+    <dg:DynamicSplitPanel AnchorWidth="450" View="Combined" AllowableViews="Combined,Master"
+                          MasterCaption="Requisition List" DetailCaption="Requisition Details"
+                          x:Name="MainPanel" OnChanged="MainPanel_OnChanged">
+        <dg:DynamicSplitPanel.Header>
+            <Border Margin="0,0,0,2" BorderBrush="Gray" BorderThickness="0.75"
                 CornerRadius="5,5,0,0" Background="WhiteSmoke">
-            <Label Content="Picked Items" VerticalContentAlignment="Center"
+                <Label Content="Requisitions" VerticalContentAlignment="Center"
                    HorizontalContentAlignment="Center"/>
-        </Border>
-        <local:RequisitionItemGrid x:Name="Items" Grid.Row="1" Grid.Column="4" />
-
-
-        <Border Grid.Row="0" Grid.Column="5" Margin="4,0,0,2" BorderBrush="Gray" BorderThickness="0.75"
-                CornerRadius="5,5,0,0" Background="WhiteSmoke">
-            <Label Content="Requisition Details" VerticalContentAlignment="Center" HorizontalContentAlignment="Center" />
-        </Border>
-
-        <Border BorderBrush="DarkGray" BorderThickness="1" Grid.Column="5" Grid.Row="1" Margin="4,0,0,2"
-                Padding="0,0,0,5">
-            <Grid>
-                <Grid.RowDefinitions>
-                    <RowDefinition Height="Auto" />
-                    <RowDefinition Height="Auto" />
-                    <RowDefinition Height="Auto" />
-                    <RowDefinition Height="1" />
-                    <RowDefinition Height="*" />
-                    <RowDefinition Height="1" />
-                    <RowDefinition Height="Auto" />
-                    <RowDefinition Height="Auto" />
-                    <RowDefinition Height="Auto" />
-                </Grid.RowDefinitions>
-                <Grid.ColumnDefinitions>
-                    <ColumnDefinition Width="120" />
-                    <ColumnDefinition Width="*" />
-                </Grid.ColumnDefinitions>
-
-                <TextBlock x:Name="Title" Text=" " Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" FontSize="16"
-                           FontWeight="Bold" TextWrapping="Wrap" Margin="5,5,5,5" Padding="5,0,0,0" MinHeight="40" />
-                <Label Content="Requested By:" Grid.Row="1" Grid.Column="0" FontSize="16" FontWeight="Bold"
-                       HorizontalContentAlignment="Left" Margin="5,5,0,0" />
-                <Label x:Name="RequestedBy" Grid.Row="1" Grid.Column="1" FontSize="16" FontWeight="Bold"
-                       HorizontalContentAlignment="Left" Margin="5,5,0,0" />
-                <Label Content="Delivery Due:" Grid.Row="2" Grid.Column="0" FontSize="16" FontWeight="Bold"
-                       HorizontalContentAlignment="Left" Margin="5,5,0,5" />
-                <Label x:Name="DueDate" Grid.Row="2" Grid.Column="1" FontSize="16" FontWeight="Bold"
-                       HorizontalContentAlignment="Left" Margin="5,5,0,5" />
-
-
-                <Border BorderBrush="DarkGray" BorderThickness="1" Grid.Row="3" Grid.Column="0" Grid.ColumnSpan="2" />
-
-                <TextBlock x:Name="Request" Grid.Row="4" TextWrapping="Wrap" FontSize="16" Grid.Column="0"
-                           Grid.ColumnSpan="2" Padding="10,5,5,5" Background="LightYellow" />
-
-                <Border BorderBrush="DarkGray" BorderThickness="1" Grid.Row="5" Grid.Column="0" Grid.ColumnSpan="2" />
-
-                <Label Content="Pick Status:" Grid.Row="6" Grid.Column="0" FontSize="16" FontWeight="Bold"
-                       HorizontalContentAlignment="Center" Margin="5,5,0,0" VerticalContentAlignment="Center" />
-                <Button x:Name="MarkAsFilled" Grid.Row="6" Grid.Column="1" Click="MarkAsFilled_Click" Margin="5,5,5,0"
-                        Padding="5">
-                    <Button.Content>
+            </Border>
+        </dg:DynamicSplitPanel.Header>
+        <dg:DynamicSplitPanel.Master>
+            <local:RequisitionGrid x:Name="Requisitions" OnSelectItem="Requisitions_OnSelectItem" />
+        </dg:DynamicSplitPanel.Master>
+        <dg:DynamicSplitPanel.Detail>
+            <dg:DynamicSplitPanel View="Combined" Anchor="Detail" AnchorWidth="450" AllowableViews="Combined"
+                                  x:Name="DetailsPanel" OnChanged="MainPanel_OnChanged">
+                <dg:DynamicSplitPanel.Header>
+                    <Border Margin="0,0,0,2" BorderBrush="Gray" BorderThickness="0.75"
+                            CornerRadius="5,5,0,0" Background="WhiteSmoke">
+                        <Label Content="Items"
+                               VerticalContentAlignment="Center" HorizontalContentAlignment="Center"/>
+                    </Border>
+                </dg:DynamicSplitPanel.Header>
+                <dg:DynamicSplitPanel.Master>
+                    <local:RequisitionItemGrid x:Name="Items" Grid.Row="1" Grid.Column="2" />
+                </dg:DynamicSplitPanel.Master>
+                <dg:DynamicSplitPanel.DetailHeader>
+                    <Border Margin="4,0,0,2" BorderBrush="Gray" BorderThickness="0.75"
+                            CornerRadius="5,5,0,0" Background="WhiteSmoke">
+                        <Label Content="Requisition Details" VerticalContentAlignment="Center" HorizontalContentAlignment="Center" />
+                    </Border>
+                </dg:DynamicSplitPanel.DetailHeader>
+                <dg:DynamicSplitPanel.Detail>
+                    <Border BorderBrush="DarkGray" BorderThickness="1" Margin="4,0,0,2"
+                            Padding="0,0,0,5">
                         <Grid>
+                            <Grid.RowDefinitions>
+                                <RowDefinition Height="Auto" />
+                                <RowDefinition Height="Auto" />
+                                <RowDefinition Height="Auto" />
+                                <RowDefinition Height="1" />
+                                <RowDefinition Height="*" />
+                                <RowDefinition Height="1" />
+                                <RowDefinition Height="Auto" />
+                                <RowDefinition Height="Auto" />
+                                <RowDefinition Height="Auto" />
+                            </Grid.RowDefinitions>
                             <Grid.ColumnDefinitions>
-                                <ColumnDefinition Width="60" />
-                                <ColumnDefinition Width="250" />
+                                <ColumnDefinition Width="120" />
+                                <ColumnDefinition Width="*" />
                             </Grid.ColumnDefinitions>
-                            <Image x:Name="PickImage" Source="pack://application:,,,/Resources/tick.png" Height="30"
-                                   Grid.Column="0" />
-                            <Label x:Name="MarkAsFilledDescription" Content="Mark As Filled" FontSize="16"
-                                   FontWeight="Bold" Grid.Column="1" HorizontalContentAlignment="Center" />
-                        </Grid>
-                    </Button.Content>
-                </Button>
 
-                <Label Content="Taken By:" Grid.Row="7" Grid.Column="0" FontSize="16" FontWeight="Bold"
-                       HorizontalContentAlignment="Center" Margin="5,5,0,0" VerticalContentAlignment="Center" />
-                <Button x:Name="TakenBy" Grid.Row="7" Grid.Column="1" Click="TakenBy_Click" Margin="5,5,5,0"
-                        Padding="5">
-                    <Button.Content>
-                        <Grid>
-                            <Grid.ColumnDefinitions>
-                                <ColumnDefinition Width="60" />
-                                <ColumnDefinition Width="250" />
-                            </Grid.ColumnDefinitions>
-                            <Image x:Name="TruckImage" Source="pack://application:,,,/Resources/truck.png" Height="30"
-                                   Grid.Column="0" />
-                            <Label x:Name="TakenByDescription" Content="Select Employee" FontSize="16"
-                                   FontWeight="Bold" Grid.Column="1" HorizontalContentAlignment="Center" />
+                            <TextBlock x:Name="Title" Text=" " Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" FontSize="16"
+                                       FontWeight="Bold" TextWrapping="Wrap" Margin="5,5,5,5" Padding="5,0,0,0" MinHeight="40" />
+                            <Label Content="Requested By:" Grid.Row="1" Grid.Column="0" FontSize="16" FontWeight="Bold"
+                                   HorizontalContentAlignment="Left" Margin="5,5,0,0" />
+                            <Label x:Name="RequestedBy" Grid.Row="1" Grid.Column="1" FontSize="16" FontWeight="Bold"
+                                   HorizontalContentAlignment="Left" Margin="5,5,0,0" />
+                            <Label Content="Delivery Due:" Grid.Row="2" Grid.Column="0" FontSize="16" FontWeight="Bold"
+                                   HorizontalContentAlignment="Left" Margin="5,5,0,5" />
+                            <Label x:Name="DueDate" Grid.Row="2" Grid.Column="1" FontSize="16" FontWeight="Bold"
+                                   HorizontalContentAlignment="Left" Margin="5,5,0,5" />
+
+
+                            <Border BorderBrush="DarkGray" BorderThickness="1" Grid.Row="3" Grid.Column="0" Grid.ColumnSpan="2" />
+
+                            <TextBlock x:Name="Request" Grid.Row="4" TextWrapping="Wrap" FontSize="16" Grid.Column="0"
+                                       Grid.ColumnSpan="2" Padding="10,5,5,5" Background="LightYellow" />
+
+                            <Border BorderBrush="DarkGray" BorderThickness="1" Grid.Row="5" Grid.Column="0" Grid.ColumnSpan="2" />
+
+                            <Label Content="Pick Status:" Grid.Row="6" Grid.Column="0" FontSize="16" FontWeight="Bold"
+                                   HorizontalContentAlignment="Center" Margin="5,5,0,0" VerticalContentAlignment="Center" />
+                            <Button x:Name="MarkAsFilled" Grid.Row="6" Grid.Column="1" Click="MarkAsFilled_Click" Margin="5,5,5,0"
+                                    Padding="5">
+                                <Button.Content>
+                                    <Grid>
+                                        <Grid.ColumnDefinitions>
+                                            <ColumnDefinition Width="60" />
+                                            <ColumnDefinition Width="250" />
+                                        </Grid.ColumnDefinitions>
+                                        <Image x:Name="PickImage" Source="pack://application:,,,/Resources/tick.png" Height="30"
+                                               Grid.Column="0" />
+                                        <Label x:Name="MarkAsFilledDescription" Content="Mark As Filled" FontSize="16"
+                                               FontWeight="Bold" Grid.Column="1" HorizontalContentAlignment="Center" />
+                                    </Grid>
+                                </Button.Content>
+                            </Button>
+
+                            <Label Content="Taken By:" Grid.Row="7" Grid.Column="0" FontSize="16" FontWeight="Bold"
+                                   HorizontalContentAlignment="Center" Margin="5,5,0,0" VerticalContentAlignment="Center" />
+                            <Button x:Name="TakenBy" Grid.Row="7" Grid.Column="1" Click="TakenBy_Click" Margin="5,5,5,0"
+                                    Padding="5">
+                                <Button.Content>
+                                    <Grid>
+                                        <Grid.ColumnDefinitions>
+                                            <ColumnDefinition Width="60" />
+                                            <ColumnDefinition Width="250" />
+                                        </Grid.ColumnDefinitions>
+                                        <Image x:Name="TruckImage" Source="pack://application:,,,/Resources/truck.png" Height="30"
+                                               Grid.Column="0" />
+                                        <Label x:Name="TakenByDescription" Content="Select Employee" FontSize="16"
+                                               FontWeight="Bold" Grid.Column="1" HorizontalContentAlignment="Center" />
+                                    </Grid>
+
+                                </Button.Content>
+                            </Button>
+
+                            <Label Content="Warehouse:" Grid.Row="8" Grid.Column="0" FontSize="16" FontWeight="Bold"
+                                   HorizontalContentAlignment="Center" Margin="5,5,0,0" VerticalContentAlignment="Center" />
+                            <Button x:Name="UpdateStock" Grid.Row="8" Grid.Column="1" Click="UpdateStock_Click" Margin="5,5,5,0"
+                                    Padding="5">
+                                <Button.Content>
+                                    <Grid>
+                                        <Grid.ColumnDefinitions>
+                                            <ColumnDefinition Width="60" />
+                                            <ColumnDefinition Width="250" />
+                                        </Grid.ColumnDefinitions>
+                                        <Image x:Name="StockImage" Source="pack://application:,,,/Resources/forklift.png"
+                                               Height="30" Grid.Column="0" />
+                                        <Label x:Name="UpdateStockDescription" Content="Update Stock Holdings" FontSize="16"
+                                               FontWeight="Bold" Grid.Column="1" HorizontalContentAlignment="Center" />
+                                    </Grid>
+                                </Button.Content>
+                            </Button>
                         </Grid>
-
-                    </Button.Content>
-                </Button>
-
-                <Label Content="Warehouse:" Grid.Row="8" Grid.Column="0" FontSize="16" FontWeight="Bold"
-                       HorizontalContentAlignment="Center" Margin="5,5,0,0" VerticalContentAlignment="Center" />
-                <Button x:Name="UpdateStock" Grid.Row="8" Grid.Column="1" Click="UpdateStock_Click" Margin="5,5,5,0"
-                        Padding="5">
-                    <Button.Content>
-                        <Grid>
-                            <Grid.ColumnDefinitions>
-                                <ColumnDefinition Width="60" />
-                                <ColumnDefinition Width="250" />
-                            </Grid.ColumnDefinitions>
-                            <Image x:Name="StockImage" Source="pack://application:,,,/Resources/forklift.png"
-                                   Height="30" Grid.Column="0" />
-                            <Label x:Name="UpdateStockDescription" Content="Update Stock Holdings" FontSize="16"
-                                   FontWeight="Bold" Grid.Column="1" HorizontalContentAlignment="Center" />
-                        </Grid>
-                    </Button.Content>
-                </Button>
-
-
-            </Grid>
-
-        </Border>
-
-
-    </Grid>
+                    </Border>
+                </dg:DynamicSplitPanel.Detail>
+            </dg:DynamicSplitPanel>
+        </dg:DynamicSplitPanel.Detail>
+    </dg:DynamicSplitPanel>
 </UserControl>

+ 382 - 385
prs.desktop/Panels/Requisitions/RequisitionPanel.xaml.cs

@@ -7,6 +7,7 @@ using System.Windows;
 using System.Windows.Controls;
 using Comal.Classes;
 using InABox.Clients;
+using InABox.Configuration;
 using InABox.Core;
 using InABox.DynamicGrid;
 using InABox.WPF;
@@ -16,511 +17,507 @@ using Motorola.Snapi.EventArguments;
 
 //using RestSharp;
 
-namespace PRSDesktop
+namespace PRSDesktop;
+
+public class RequisitionPanelSettings : IUserConfigurationSettings
 {
-    /// <summary>
-    ///     Interaction logic for RequisitionPanel.xaml
-    /// </summary>
-    public partial class RequisitionPanel : UserControl, IPanel<Requisition>
-    {
-        private Requisition? _requisition;
+    public ScreenViewType ViewType { get; set; } = ScreenViewType.Combined;
 
-        public List<IMotorolaBarcodeScanner> Scanners = new();
+    public double RequisitionsWidth { get; set; } = 450;
 
-        public RequisitionPanel()
-        {
-            InitializeComponent();
-            PickImage.Source = PRSDesktop.Resources.tick.AsBitmapImage(Color.White);
-            StockImage.Source = PRSDesktop.Resources.forklift.AsBitmapImage(Color.White);
-            TruckImage.Source = PRSDesktop.Resources.truck.AsBitmapImage();
-        }
+    public double DetailsWidth { get; set; } = 450;
+}
 
-        //DateTime lastselection = DateTime.MaxValue;
-        //DispatcherTimer timer = new DispatcherTimer();
+/// <summary>
+///     Interaction logic for RequisitionPanel.xaml
+/// </summary>
+public partial class RequisitionPanel : UserControl, IPanel<Requisition>
+{
+    private Requisition? _requisition;
+    private RequisitionPanelSettings Settings;
 
-        public event DataModelUpdateEvent? OnUpdateDataModel;
+    public List<IMotorolaBarcodeScanner> Scanners = new();
 
-        public bool IsReady { get; set; }
+    public RequisitionPanel()
+    {
+        InitializeComponent();
+        PickImage.Source = PRSDesktop.Resources.tick.AsBitmapImage(Color.White);
+        StockImage.Source = PRSDesktop.Resources.forklift.AsBitmapImage(Color.White);
+        TruckImage.Source = PRSDesktop.Resources.truck.AsBitmapImage();
+    }
 
-        public Dictionary<string, object[]> Selected()
-        {
-            return new Dictionary<string, object[]>
-            {
-                { typeof(Requisition).EntityName(), Requisitions.SelectedRows },
-                { typeof(RequisitionItem).EntityName(), Items.SelectedRows }
-            };
-        }
+    //DateTime lastselection = DateTime.MaxValue;
+    //DispatcherTimer timer = new DispatcherTimer();
 
-        public void Setup()
+    public event DataModelUpdateEvent? OnUpdateDataModel;
+
+    public bool IsReady { get; set; }
+
+    public Dictionary<string, object[]> Selected()
+    {
+        return new Dictionary<string, object[]>
         {
-            //Requisitions.OnSelectItem += Requisitions_OnSelectItem;
+            { typeof(Requisition).EntityName(), Requisitions.SelectedRows },
+            { typeof(RequisitionItem).EntityName(), Items.SelectedRows }
+        };
+    }
+
+    public void Setup()
+    {
+        //Requisitions.OnSelectItem += Requisitions_OnSelectItem;
 
-            //Requisitions.OnRequisitionFillStateChanged += Requisitions_OnRequisitionFillStateChanged;
-            //Requisitions.OnRequisitionBoxesChanged += Requisitions_OnRequisitionBoxesChanged;
+        //Requisitions.OnRequisitionFillStateChanged += Requisitions_OnRequisitionFillStateChanged;
+        //Requisitions.OnRequisitionBoxesChanged += Requisitions_OnRequisitionBoxesChanged;
 
-            UnPickedItems.Picked = false;
-            UnPickedItems.Refresh(true, true);
+        LoadSettings();
 
-            SetupScanner();
+        SetupScanner();
 
-            Items.Reconfigure(options =>
+        Items.Reconfigure(options =>
+        {
+            options.BeginUpdate();
+            if (_requisition != null)
             {
-                options.BeginUpdate();
-                if (_requisition != null)
+                if (_requisition.Filled.IsEmpty())
                 {
-                    if (_requisition.Filled.IsEmpty())
-                    {
-                        options.Add(DynamicGridOption.AddRows);
-                        options.Add(DynamicGridOption.DeleteRows);
-                    }
-                    else
-                    {
-                        options.Remove(DynamicGridOption.AddRows);
-                        options.Remove(DynamicGridOption.DeleteRows);
-                    }
+                    options.Add(DynamicGridOption.AddRows);
+                    options.Add(DynamicGridOption.DeleteRows);
                 }
+                else
+                {
+                    options.Remove(DynamicGridOption.AddRows);
+                    options.Remove(DynamicGridOption.DeleteRows);
+                }
+            }
 
-                options.EndUpdate();
-            });
+            options.EndUpdate();
+        });
 
-            Requisitions.Refresh(true, false);
-            Items.Refresh(true, false);
+        Requisitions.Refresh(true, false);
+        Items.Refresh(true, false);
 
-            UpdateLayout();
-        }
+        UpdateLayout();
+    }
 
-        public void Shutdown(CancelEventArgs? cancel)
-        {
-            ShutdownScanner();
-        }
+    private void LoadSettings()
+    {
+        Settings = new UserConfiguration<RequisitionPanelSettings>().Load();
+        MainPanel.View = Settings.ViewType == ScreenViewType.Register ? DynamicSplitPanelView.Master :
+            Settings.ViewType == ScreenViewType.Details ? DynamicSplitPanelView.Detail : DynamicSplitPanelView.Combined;
+        MainPanel.AnchorWidth = Settings.RequisitionsWidth;
 
-        public void CreateToolbarButtons(IPanelHost host)
+        DetailsPanel.AnchorWidth = Settings.DetailsWidth;
+    }
+    private void SaveSettings()
+    {
+        Settings.ViewType = MainPanel.View switch
         {
-            //host.CreatePanelAction(new PanelAction() { Caption = "Archive Requisition", Image = PRSDesktop.Resources.delete, OnExecute = ArchiveRequisition });
-        }
+            DynamicSplitPanelView.Master => ScreenViewType.Register,
+            DynamicSplitPanelView.Detail => ScreenViewType.Details,
+            DynamicSplitPanelView.Combined or _ => ScreenViewType.Combined
+        };
+        Settings.RequisitionsWidth = MainPanel.AnchorWidth;
+        Settings.DetailsWidth = DetailsPanel.AnchorWidth;
+        new UserConfiguration<RequisitionPanelSettings>().Save(Settings);
+    }
 
-        public string SectionName => "Requisitions";
-        public DataModel DataModel(Selection selection)
-        {
-            var ids = Requisitions.ExtractValues(x => x.ID, selection).ToArray();
-            return new BaseDataModel<Requisition>(new Filter<Requisition>(x => x.ID).InList(ids));
-        }
+    private void MainPanel_OnChanged(object sender, DynamicSplitPanelSettings e)
+    {
+        SaveSettings();
+    }
 
-        public void Refresh()
-        {
-            Requisitions.Refresh(false, true);
-            //lastselection = DateTime.MinValue;
-            //Items.Refresh(true, false);
-        }
+    public void Shutdown(CancelEventArgs? cancel)
+    {
+        ShutdownScanner();
+    }
 
-        public void Heartbeat(TimeSpan time)
-        {
-            // Nothing to do here
-        }
+    public void CreateToolbarButtons(IPanelHost host)
+    {
+        //host.CreatePanelAction(new PanelAction() { Caption = "Archive Requisition", Image = PRSDesktop.Resources.delete, OnExecute = ArchiveRequisition });
+    }
 
-        private void ShutdownScanner()
-        {
-            try
-            {
-                foreach (var scanner in Scanners) scanner.Actions.ToggleLed(LedMode.GreenOff);
-                BarcodeScannerManager.Instance.DataReceived -= Instance_DataReceived;
+    public string SectionName => "Requisitions";
+    public DataModel DataModel(Selection selection)
+    {
+        var ids = Requisitions.ExtractValues(x => x.ID, selection).ToArray();
+        return new BaseDataModel<Requisition>(new Filter<Requisition>(x => x.ID).InList(ids));
+    }
 
-                BarcodeScannerManager.Instance.Close();
-            }
-            catch (Exception e)
-            {
-                MessageBox.Show("Error Shutting down Scanner!\n\n" + e.Message);
-            }
-        }
+    public void Refresh()
+    {
+        Requisitions.Refresh(false, true);
+        //lastselection = DateTime.MinValue;
+        //Items.Refresh(true, false);
+    }
 
-        private void SetupScanner()
+    public void Heartbeat(TimeSpan time)
+    {
+        // Nothing to do here
+    }
+
+    private void ShutdownScanner()
+    {
+        try
         {
-            Scanners.Clear();
-            BarcodeScannerManager.Instance.Open();
+            foreach (var scanner in Scanners) scanner.Actions.ToggleLed(LedMode.GreenOff);
+            BarcodeScannerManager.Instance.DataReceived -= Instance_DataReceived;
 
-            BarcodeScannerManager.Instance.RegisterForEvents(EventType.Barcode, EventType.Pnp, EventType.Image, EventType.Other, EventType.Rmd);
+            BarcodeScannerManager.Instance.Close();
+        }
+        catch (Exception e)
+        {
+            MessageBox.Show("Error Shutting down Scanner!\n\n" + e.Message);
+        }
+    }
 
-            BarcodeScannerManager.Instance.GetDevices();
-            foreach (var scanner in BarcodeScannerManager.Instance.GetDevices())
-            {
-                Scanners.Add(scanner);
-                scanner.Actions.ToggleLed(LedMode.RedOn);
-                scanner.Actions.SoundBeeper(BeepPattern.FastWarble);
-            }
+    private void SetupScanner()
+    {
+        Scanners.Clear();
+        BarcodeScannerManager.Instance.Open();
 
-            BarcodeScannerManager.Instance.DataReceived += Instance_DataReceived;
-        }
+        BarcodeScannerManager.Instance.RegisterForEvents(EventType.Barcode, EventType.Pnp, EventType.Image, EventType.Other, EventType.Rmd);
 
-        private void Instance_DataReceived(object? sender, BarcodeScanEventArgs e)
+        BarcodeScannerManager.Instance.GetDevices();
+        foreach (var scanner in BarcodeScannerManager.Instance.GetDevices())
         {
-            Dispatcher.Invoke(() => { ProcessCode(Scanners[(int)e.ScannerId], e.Data); });
+            Scanners.Add(scanner);
+            scanner.Actions.ToggleLed(LedMode.RedOn);
+            scanner.Actions.SoundBeeper(BeepPattern.FastWarble);
         }
 
-        private void ProcessCode(IMotorolaBarcodeScanner scanner, string code)
+        BarcodeScannerManager.Instance.DataReceived += Instance_DataReceived;
+    }
+
+    private void Instance_DataReceived(object? sender, BarcodeScanEventArgs e)
+    {
+        Dispatcher.Invoke(() => { ProcessCode(Scanners[(int)e.ScannerId], e.Data); });
+    }
+
+    private void ProcessCode(IMotorolaBarcodeScanner scanner, string code)
+    {
+        try
         {
-            try
-            {
-                var iRow = Requisitions.SelectedRows.First().Index;
-                if (iRow == -1)
-                    throw new Exception("Please select a Requsition First");
+            var iRow = Requisitions.SelectedRows.First().Index;
+            if (iRow == -1)
+                throw new Exception("Please select a Requsition First");
 
-                var row = Requisitions.Data.Rows[iRow];
-                var filled = row.Get<Requisition, DateTime>(x => x.Filled);
+            var row = Requisitions.Data.Rows[iRow];
+            var filled = row.Get<Requisition, DateTime>(x => x.Filled);
 
-                if (!filled.IsEmpty())
-                    throw new Exception("Cannot Add Items to a completed Requisition");
+            if (!filled.IsEmpty())
+                throw new Exception("Cannot Add Items to a completed Requisition");
 
-                var reqid = row.Get<Requisition, Guid>(x => x.ID);
+            var reqid = row.Get<Requisition, Guid>(x => x.ID);
 
-                var boxes = row.Get<Requisition, int>(x => x.Boxes);
+            var boxes = row.Get<Requisition, int>(x => x.Boxes);
 
-                var sCode = code;
-                var iQty = 1;
-                if (sCode.Contains('*'))
-                {
-                    var comps = sCode.Split('*');
-                    sCode = comps[0];
-                    iQty = int.Parse(comps[1].Trim());
-                }
+            var sCode = code;
+            var iQty = 1;
+            if (sCode.Contains('*'))
+            {
+                var comps = sCode.Split('*');
+                sCode = comps[0];
+                iQty = int.Parse(comps[1].Trim());
+            }
 
-                RequisitionItem? item = null;
-                CoreRow? itemrow = null;
-                try
-                {
-                    itemrow = Items.Data.Rows.FirstOrDefault(r => /* r.Get<RequisitionItem, int>(x => x.BoxNumber).Equals(boxes) && */
-                        r.Get<RequisitionItem, string>(x => x.BarCode).Equals(sCode));
-                    //itemrow = Items.Data.Rows.FirstOrDefault(r => r.Get<RequisitionItem, String>(x => x.BarCode).Equals(sCode));
-                }
-                catch (Exception e)
-                {
-                    Logger.Send(LogType.Error, "", string.Format("*** Unknown Error: {0}\n{1}", e.Message, e.StackTrace));
-                }
+            RequisitionItem? item = null;
+            CoreRow? itemrow = null;
+            try
+            {
+                itemrow = Items.Data.Rows.FirstOrDefault(r => /* r.Get<RequisitionItem, int>(x => x.BoxNumber).Equals(boxes) && */
+                    r.Get<RequisitionItem, string>(x => x.BarCode).Equals(sCode));
+                //itemrow = Items.Data.Rows.FirstOrDefault(r => r.Get<RequisitionItem, String>(x => x.BarCode).Equals(sCode));
+            }
+            catch (Exception e)
+            {
+                Logger.Send(LogType.Error, "", string.Format("*** Unknown Error: {0}\n{1}", e.Message, e.StackTrace));
+            }
 
-                if (itemrow != null)
-                    item = new Client<RequisitionItem>()
-                        .Load(new Filter<RequisitionItem>(x => x.ID).IsEqualTo(itemrow.Get<RequisitionItem, Guid>(x => x.ID))).FirstOrDefault();
-                if (item != null)
+            if (itemrow != null)
+                item = new Client<RequisitionItem>()
+                    .Load(new Filter<RequisitionItem>(x => x.ID).IsEqualTo(itemrow.Get<RequisitionItem, Guid>(x => x.ID))).FirstOrDefault();
+            if (item != null)
+            {
+                item.Quantity += iQty;
+                new Client<RequisitionItem>().Save(item, "Quantity Updated by Barcode Scanner");
+                scanner?.Actions.SoundBeeper(BeepPattern.LowHigh);
+                Refresh();
+            }
+            else
+            {
+                var product = new Client<Product>().Load(new Filter<Product>(x => x.Code).IsEqualTo(sCode)).FirstOrDefault();
+                if (product != null)
                 {
-                    item.Quantity += iQty;
-                    new Client<RequisitionItem>().Save(item, "Quantity Updated by Barcode Scanner");
+                    item = new RequisitionItem
+                    {
+                        RequisitionLink = new RequisitionLink { ID = reqid },
+                        //BoxNumber = boxes,
+                        Code = product.Code,
+                        Description = product.Name,
+                        BarCode = sCode,
+                        Quantity = iQty
+                    };
+                    new Client<RequisitionItem>().Save(item, "Scanned by Barcode Reader");
+
                     scanner?.Actions.SoundBeeper(BeepPattern.LowHigh);
+
                     Refresh();
                 }
                 else
                 {
-                    var product = new Client<Product>().Load(new Filter<Product>(x => x.Code).IsEqualTo(sCode)).FirstOrDefault();
-                    if (product != null)
-                    {
-                        item = new RequisitionItem
-                        {
-                            RequisitionLink = new RequisitionLink { ID = reqid },
-                            //BoxNumber = boxes,
-                            Code = product.Code,
-                            Description = product.Name,
-                            BarCode = sCode,
-                            Quantity = iQty
-                        };
-                        new Client<RequisitionItem>().Save(item, "Scanned by Barcode Reader");
-
-                        scanner?.Actions.SoundBeeper(BeepPattern.LowHigh);
-
-                        Refresh();
-                    }
-                    else
-                    {
-                        scanner?.Actions.SoundBeeper(BeepPattern.FourLowLong);
-                    }
+                    scanner?.Actions.SoundBeeper(BeepPattern.FourLowLong);
                 }
             }
-            catch (Exception)
-            {
-                scanner?.Actions.SoundBeeper(BeepPattern.FourLowShort);
-            }
         }
+        catch (Exception)
+        {
+            scanner?.Actions.SoundBeeper(BeepPattern.FourLowShort);
+        }
+    }
 
-        /*private void ArchiveRequisition(PanelAction obj)
+    /*private void ArchiveRequisition(PanelAction obj)
+    {
+        var bClosed = false;
+        var iRow = Requisitions.SelectedRows.First().Index;
+        if (iRow > -1)
         {
-            var bClosed = false;
-            var iRow = Requisitions.SelectedRows.First().Index;
-            if (iRow > -1)
+            var row = Requisitions.Data.Rows[iRow];
+            var id = row.Get<Requisition, Guid>(x => x.ID);
+            var filled = row.Get<Requisition, DateTime>(x => x.Filled);
+            if (filled.IsEmpty())
             {
-                var row = Requisitions.Data.Rows[iRow];
-                var id = row.Get<Requisition, Guid>(x => x.ID);
-                var filled = row.Get<Requisition, DateTime>(x => x.Filled);
-                if (filled.IsEmpty())
-                {
-                    MessageBox.Show("Please complete this requisition before Archiving it!");
-                }
-                else
-                {
-                    var req = new Client<Requisition>().Load(new Filter<Requisition>(x => x.ID).IsEqualTo(id)).FirstOrDefault();
-                    if (req != null)
-                    {
-                        req.Archived = DateTime.Now;
-                        new Client<Requisition>().Save(req, "Requisition Archived");
-                        bClosed = true;
-                    }
-                }
+                MessageBox.Show("Please complete this requisition before Archiving it!");
             }
             else
             {
-                MessageBox.Show("Please select a requisition first!");
+                var req = new Client<Requisition>().Load(new Filter<Requisition>(x => x.ID).IsEqualTo(id)).FirstOrDefault();
+                if (req != null)
+                {
+                    req.Archived = DateTime.Now;
+                    new Client<Requisition>().Save(req, "Requisition Archived");
+                    bClosed = true;
+                }
             }
+        }
+        else
+        {
+            MessageBox.Show("Please select a requisition first!");
+        }
 
-            if (bClosed)
-                Refresh();
-        }*/
+        if (bClosed)
+            Refresh();
+    }*/
 
-        public Dictionary<Type, CoreTable> DataEnvironment()
+    public Dictionary<Type, CoreTable> DataEnvironment()
+    {
+        return new Dictionary<Type, CoreTable>
         {
-            return new Dictionary<Type, CoreTable>
-            {
-                [typeof(Requisition)] = Requisitions.Data,
-                [typeof(RequisitionItem)] = Items.Data
-            };
-        }
+            [typeof(Requisition)] = Requisitions.Data,
+            [typeof(RequisitionItem)] = Items.Data
+        };
+    }
 
-        //private void Timer_Tick(object sender, EventArgs e)
-        //{
+    //private void Timer_Tick(object sender, EventArgs e)
+    //{
 
-        //    if (lastselection < DateTime.Now.AddMilliseconds(-500))
-        //    {
-        //        lastselection = DateTime.MaxValue;
+    //    if (lastselection < DateTime.Now.AddMilliseconds(-500))
+    //    {
+    //        lastselection = DateTime.MaxValue;
 
-        //        LoadRequisition();
+    //        LoadRequisition();
 
-        //    }
+    //    }
 
-        //}
+    //}
 
-        private void LoadRequisition()
-        {
-            foreach (var scanner in Scanners)
-                scanner.Actions.ToggleLed(_requisition != null ? LedMode.GreenOn : LedMode.RedOn);
+    private void LoadRequisition()
+    {
+        foreach (var scanner in Scanners)
+            scanner.Actions.ToggleLed(_requisition != null ? LedMode.GreenOn : LedMode.RedOn);
 
 
-            Title.Text = _requisition != null ? _requisition.Title : "";
+        Title.Text = _requisition != null ? _requisition.Title : "";
 
-            RequestedBy.Content = _requisition != null ? _requisition.RequestedBy.Name : "";
+        RequestedBy.Content = _requisition != null ? _requisition.RequestedBy.Name : "";
 
-            DueDate.Content = _requisition != null ? string.Format("{0:dddd, dd MMM yyyy}", _requisition.Due) : "";
+        DueDate.Content = _requisition != null ? string.Format("{0:dddd, dd MMM yyyy}", _requisition.Due) : "";
 
-            var notes = _requisition != null ? _requisition.Notes : Array.Empty<string>();
-            var request = _requisition != null ? CoreUtils.StripHTML(_requisition.Request) : "";
-            Request.Text = string.Join("\n===============================\n", Utility.ProcessNotes(notes, request));
+        var notes = _requisition != null ? _requisition.Notes : Array.Empty<string>();
+        var request = _requisition != null ? CoreUtils.StripHTML(_requisition.Request) : "";
+        Request.Text = string.Join("\n===============================\n", Utility.ProcessNotes(notes, request));
 
-            MarkAsFilled.IsEnabled = _requisition != null && _requisition.Archived.IsEmpty() && _requisition.StockUpdated.IsEmpty();
-            MarkAsFilledDescription.Content = _requisition == null || _requisition.Filled.IsEmpty() ? "Mark As Filled" : "Clear Filled Flag";
+        MarkAsFilled.IsEnabled = _requisition != null && _requisition.Archived.IsEmpty() && _requisition.StockUpdated.IsEmpty();
+        MarkAsFilledDescription.Content = _requisition == null || _requisition.Filled.IsEmpty() ? "Mark As Filled" : "Clear Filled Flag";
 
-            UpdateStock.IsEnabled = Security.IsAllowed<CanUpdateRequisitionStockMovements>() && _requisition != null &&
-                                    !_requisition.Filled.IsEmpty();
-            UpdateStockDescription.Content =
-                _requisition == null || _requisition.StockUpdated.IsEmpty() ? "Update Stock Holdings" : "Clear Stock Movements";
+        UpdateStock.IsEnabled = Security.IsAllowed<CanUpdateRequisitionStockMovements>() && _requisition != null &&
+                                !_requisition.Filled.IsEmpty();
+        UpdateStockDescription.Content =
+            _requisition == null || _requisition.StockUpdated.IsEmpty() ? "Update Stock Holdings" : "Clear Stock Movements";
 
-            TakenBy.IsEnabled = _requisition != null && !_requisition.Filled.IsEmpty() && _requisition.Archived.IsEmpty() &&
-                                !_requisition.Delivery.IsValid();
+        TakenBy.IsEnabled = _requisition != null && !_requisition.Filled.IsEmpty() && _requisition.Archived.IsEmpty() &&
+                            !_requisition.Delivery.IsValid();
 
-            TakenByDescription.Content = _requisition == null
-                ? "Select Employee"
-                : _requisition.Delivery.IsValid()
-                    ? _requisition.Delivery.Completed.IsEmpty()
-                        ? string.Format("Booked On Delivery #{0}", _requisition.Delivery.Number)
-                        : string.Format("Delivered on {0:dd MMM yy} (#{1})", _requisition.Delivery.Completed, _requisition.Delivery.Number)
-                    : _requisition.TakenBy.IsValid()
-                        ? string.Format("{0} ({1:dd MMM yy})", _requisition.TakenBy.Name, _requisition.Archived)
-                        : "Select Employee";
-        }
+        TakenByDescription.Content = _requisition == null
+            ? "Select Employee"
+            : _requisition.Delivery.IsValid()
+                ? _requisition.Delivery.Completed.IsEmpty()
+                    ? string.Format("Booked On Delivery #{0}", _requisition.Delivery.Number)
+                    : string.Format("Delivered on {0:dd MMM yy} (#{1})", _requisition.Delivery.Completed, _requisition.Delivery.Number)
+                : _requisition.TakenBy.IsValid()
+                    ? string.Format("{0} ({1:dd MMM yy})", _requisition.TakenBy.Name, _requisition.Archived)
+                    : "Select Employee";
+    }
 
-        private void Requisitions_OnSelectItem(object sender, DynamicGridSelectionEventArgs e)
-        {
-            _requisition = e.Rows?.FirstOrDefault()?.ToObject<Requisition>();
-            LoadRequisition();
-            UnPickedItems.Requisition = _requisition;
-            UnPickedItems.Refresh(false, true);
-            Items.Requisition = _requisition;
-            Items.Refresh(false, true);
-            //lastselection = DateTime.Now;
-            //Dispatcher.Invoke(() => { LoadRequisition(); });
-        }
+    private void Requisitions_OnSelectItem(object sender, DynamicGridSelectionEventArgs e)
+    {
+        _requisition = e.Rows?.FirstOrDefault()?.ToObject<Requisition>();
+        LoadRequisition();
+        Items.Requisition = _requisition;
+        Items.Refresh(false, true);
+        //lastselection = DateTime.Now;
+        //Dispatcher.Invoke(() => { LoadRequisition(); });
+    }
 
-        private void TakenBy_Click(object sender, RoutedEventArgs e)
-        {
-            if (_requisition == null || _requisition.ID == Guid.Empty)
-                return;
+    private void TakenBy_Click(object sender, RoutedEventArgs e)
+    {
+        if (_requisition == null || _requisition.ID == Guid.Empty)
+            return;
+
+        var dlg = new MultiSelectDialog<Employee>(
+            LookupFactory.DefineFilter<Employee>(),
+            LookupFactory.DefineColumns<Employee>(),
+            false);
 
-            var dlg = new MultiSelectDialog<Employee>(
-                LookupFactory.DefineFilter<Employee>(),
-                LookupFactory.DefineColumns<Employee>(),
-                false);
+        if (!dlg.ShowDialog())
+            return;
 
-            if (!dlg.ShowDialog())
+        if (!_requisition.Filled.IsEmpty() && !_requisition.StockUpdated.IsEmpty())
+            if (MessageBox.Show("This will remove this requisition from this list.\nAre you sure you wish to continue?", "Close Requisition?",
+                    MessageBoxButton.YesNo, MessageBoxImage.Question) != MessageBoxResult.Yes)
                 return;
 
-            if (!_requisition.Filled.IsEmpty() && !_requisition.StockUpdated.IsEmpty())
-                if (MessageBox.Show("This will remove this requisition from this list.\nAre you sure you wish to continue?", "Close Requisition?",
-                        MessageBoxButton.YesNo, MessageBoxImage.Question) != MessageBoxResult.Yes)
-                    return;
+        if (_requisition.Archived.IsEmpty())
+            _requisition.Archived = DateTime.Now;
 
-            if (_requisition.Archived.IsEmpty())
-                _requisition.Archived = DateTime.Now;
+        var emp = dlg.Data()?.Rows.FirstOrDefault();
+        _requisition.TakenBy.ID = emp != null ? emp.Get<Employee, Guid>(x => x.ID) : Guid.Empty;
+        _requisition.TakenBy.Name = emp != null ? emp.Get<Employee, string>(x => x.Name) : "";
 
-            var emp = dlg.Data()?.Rows.FirstOrDefault();
-            _requisition.TakenBy.ID = emp != null ? emp.Get<Employee, Guid>(x => x.ID) : Guid.Empty;
-            _requisition.TakenBy.Name = emp != null ? emp.Get<Employee, string>(x => x.Name) : "";
+        Progress.Show("Updating Requisition Delivery Status");
+        new Client<Requisition>().Save(_requisition, "Updated [TakenBy] Flag");
+        if (!_requisition.Filled.IsEmpty() && !_requisition.StockUpdated.IsEmpty() && !_requisition.Archived.IsEmpty())
+        {
+            Refresh();
+        }
+        else
+        {
+            Requisitions.UpdateRow<Requisition, Guid>(Requisitions.SelectedRows.First(), x => x.TakenBy.ID, _requisition.TakenBy.ID, false);
+            Requisitions.UpdateRow<Requisition, string>(Requisitions.SelectedRows.First(), x => x.TakenBy.Name, _requisition.TakenBy.Name, false);
+            Requisitions.UpdateRow<Requisition, DateTime>(Requisitions.SelectedRows.First(), x => x.Archived, _requisition.Archived);
+            LoadRequisition();
+        }
 
-            Progress.Show("Updating Requisition Delivery Status");
-            new Client<Requisition>().Save(_requisition, "Updated [TakenBy] Flag");
-            if (!_requisition.Filled.IsEmpty() && !_requisition.StockUpdated.IsEmpty() && !_requisition.Archived.IsEmpty())
-            {
-                Refresh();
-            }
-            else
-            {
-                Requisitions.UpdateRow<Requisition, Guid>(Requisitions.SelectedRows.First(), x => x.TakenBy.ID, _requisition.TakenBy.ID, false);
-                Requisitions.UpdateRow<Requisition, string>(Requisitions.SelectedRows.First(), x => x.TakenBy.Name, _requisition.TakenBy.Name, false);
-                Requisitions.UpdateRow<Requisition, DateTime>(Requisitions.SelectedRows.First(), x => x.Archived, _requisition.Archived);
-                LoadRequisition();
-            }
+        Progress.Close();
+    }
 
-            Progress.Close();
+    private void MarkAsFilled_Click(object sender, RoutedEventArgs e)
+    {
+        if (_requisition == null)
+        {
+            MessageBox.Show("Please select a Requisition first!");
+            return;
         }
 
-        private void MarkAsFilled_Click(object sender, RoutedEventArgs e)
+        DateTime filltime = DateTime.Now;
+        
+        var unpickeditems = Items.Data.Rows.Where(r =>
+            _requisition.Filled.IsEmpty()
+            && (r.Get<RequisitionItem, Guid>(x => x.Product.ID) != Guid.Empty)
+            && (r.Get<RequisitionItem, bool>(x => x.Product.NonStock) != true)
+            && (r.Get<RequisitionItem, DateTime>(x => x.Picked).IsEmpty())
+        );
+        if (unpickeditems.Any())
         {
-            if (_requisition == null)
-            {
-                MessageBox.Show("Please select a Requisition first!");
+            var confirm = MessageBox.Show("Unpicked items exist on this requisition!\n\nDo you want to mark them as picked now?",
+                "Unpicked Items", MessageBoxButton.YesNoCancel, MessageBoxImage.Question);
+            if (confirm == MessageBoxResult.Cancel)
                 return;
-            }
-
-            DateTime filltime = DateTime.Now;
-            
-            var unpickeditems = Items.Data.Rows.Where(r =>
-                _requisition.Filled.IsEmpty()
-                && (r.Get<RequisitionItem, Guid>(x => x.Product.ID) != Guid.Empty)
-                && (r.Get<RequisitionItem, bool>(x => x.Product.NonStock) != true)
-                && (r.Get<RequisitionItem, DateTime>(x => x.Picked).IsEmpty())
-            );
-            if (unpickeditems.Any())
+            filltime = DateTime.Now;
+            if (confirm == MessageBoxResult.Yes)
             {
-                var confirm = MessageBox.Show("Unpicked items exist on this requisition!\n\nDo you want to mark them as picked now?",
-                    "Unpicked Items", MessageBoxButton.YesNoCancel, MessageBoxImage.Question);
-                if (confirm == MessageBoxResult.Cancel)
-                    return;
-                filltime = DateTime.Now;
-                if (confirm == MessageBoxResult.Yes)
+                var updates = new List<RequisitionItem>();
+                foreach (var row in unpickeditems)
                 {
-                    var updates = new List<RequisitionItem>();
-                    foreach (var row in unpickeditems)
-                    {
-                        var item = row.ToObject<RequisitionItem>();
-                        item.Picked = filltime;
-                        updates.Add(item);
-                    }
-                    new Client<RequisitionItem>().Save(updates, "Marked as Picked because Requisition was marked as filled");
+                    var item = row.ToObject<RequisitionItem>();
+                    item.Picked = filltime;
+                    updates.Add(item);
                 }
+                new Client<RequisitionItem>().Save(updates, "Marked as Picked because Requisition was marked as filled");
             }
+        }
 
-            _requisition.Filled = _requisition.Filled.IsEmpty() ? filltime : DateTime.MinValue;
-            Progress.Show(_requisition.Filled.IsEmpty() ? "Clearing Delivery Items" : "Creating Delivery Items");
-            new Client<Requisition>().Save(_requisition, "Updated Filled Flag");
-            Requisitions.UpdateRow<Requisition, DateTime>(Requisitions.SelectedRows.First(), x => x.Filled, _requisition.Filled);
-            LoadRequisition();
-            Items.Refresh(false, true);
-            Progress.Close();
+        _requisition.Filled = _requisition.Filled.IsEmpty() ? filltime : DateTime.MinValue;
+        Progress.Show(_requisition.Filled.IsEmpty() ? "Clearing Delivery Items" : "Creating Delivery Items");
+        new Client<Requisition>().Save(_requisition, "Updated Filled Flag");
+        Requisitions.UpdateRow<Requisition, DateTime>(Requisitions.SelectedRows.First(), x => x.Filled, _requisition.Filled);
+        LoadRequisition();
+        Items.Refresh(false, true);
+        Progress.Close();
+    }
+
+    private void UpdateStock_Click(object sender, RoutedEventArgs e)
+    {
+        if (_requisition == null)
+        {
+            MessageBox.Show("Please select a Requisition first!");
+            return;
         }
 
-        private void UpdateStock_Click(object sender, RoutedEventArgs e)
+        if (_requisition.StockUpdated.IsEmpty())
         {
-            if (_requisition == null)
+            var emptyrows = Items.Data.Rows.Where(r =>
+                !Entity.IsEntityLinkValid<RequisitionItem, StockLocationLink>(x => x.Location, r) &&
+                r.Get<RequisitionItem, bool>(c => c.Product.NonStock).Equals(false));
+            if (emptyrows.Any())
             {
-                MessageBox.Show("Please select a Requisition first!");
+                MessageBox.Show("You must select a Holding for each non-stock Item on this Requisition!", "Missing Holdings", MessageBoxButton.OK,
+                    MessageBoxImage.Error);
                 return;
             }
 
-            if (_requisition.StockUpdated.IsEmpty())
+            if (!_requisition.Filled.IsEmpty() && !_requisition.Archived.IsEmpty())
             {
-                var emptyrows = Items.Data.Rows.Where(r =>
-                    !Entity.IsEntityLinkValid<RequisitionItem, StockLocationLink>(x => x.Location, r) &&
-                    r.Get<RequisitionItem, bool>(c => c.Product.NonStock).Equals(false));
-                if (emptyrows.Any())
-                {
-                    MessageBox.Show("You must select a Holding for each non-stock Item on this Requisition!", "Missing Holdings", MessageBoxButton.OK,
-                        MessageBoxImage.Error);
+                if (MessageBox.Show("This will remove this requisition from this list.\nAre you sure you wish to continue?", "Close Requisition?",
+                        MessageBoxButton.YesNo, MessageBoxImage.Question) != MessageBoxResult.Yes)
                     return;
-                }
-
-                if (!_requisition.Filled.IsEmpty() && !_requisition.Archived.IsEmpty())
-                {
-                    if (MessageBox.Show("This will remove this requisition from this list.\nAre you sure you wish to continue?", "Close Requisition?",
-                            MessageBoxButton.YesNo, MessageBoxImage.Question) != MessageBoxResult.Yes)
-                        return;
-                }
-                else
-                {
-                    if (MessageBox.Show("Update Stock Movements?", "Confirm", MessageBoxButton.YesNo) != MessageBoxResult.Yes)
-                        return;
-                }
-
-                _requisition.StockUpdated = DateTime.Now;
             }
             else
             {
-                if (MessageBox.Show("Clear Stock Movements?", "Confirm", MessageBoxButton.YesNo) != MessageBoxResult.Yes)
+                if (MessageBox.Show("Update Stock Movements?", "Confirm", MessageBoxButton.YesNo) != MessageBoxResult.Yes)
                     return;
-                _requisition.StockUpdated = DateTime.MinValue;
-            }
-
-            Progress.Show("Updating Stock Holdings");
-            new Client<Requisition>().Save(_requisition, "Updated Stock Flag");
-            if (!_requisition.Filled.IsEmpty() && !_requisition.StockUpdated.IsEmpty() && !_requisition.Archived.IsEmpty())
-            {
-                Refresh();
-            }
-            else
-            {
-                Requisitions.UpdateRow<Requisition, DateTime>(Requisitions.SelectedRows.First(), x => x.StockUpdated, _requisition.StockUpdated);
-                LoadRequisition();
             }
 
-            Progress.Close();
+            _requisition.StockUpdated = DateTime.Now;
         }
-
-
-        private void PickItems_Click(object sender, RoutedEventArgs e)
+        else
         {
-            if (!UnPickedItems.SelectedRows.Any())
+            if (MessageBox.Show("Clear Stock Movements?", "Confirm", MessageBoxButton.YesNo) != MessageBoxResult.Yes)
                 return;
-
-            ProcessItems(DateTime.Now, UnPickedItems.SelectedRows);
+            _requisition.StockUpdated = DateTime.MinValue;
         }
 
-        private void UnPickItems_Click(object sender, RoutedEventArgs e)
+        Progress.Show("Updating Stock Holdings");
+        new Client<Requisition>().Save(_requisition, "Updated Stock Flag");
+        if (!_requisition.Filled.IsEmpty() && !_requisition.StockUpdated.IsEmpty() && !_requisition.Archived.IsEmpty())
         {
-            if (!Items.SelectedRows.Any())
-                return;
-
-            ProcessItems(DateTime.MinValue, Items.SelectedRows);
+            Refresh();
         }
-
-        private void ProcessItems(DateTime picked, CoreRow[] rows)
+        else
         {
-            var list = new List<RequisitionItem>();
-            foreach (CoreRow row in rows)
-            {
-                var item = row.ToObject<RequisitionItem>();
-                item.Picked = picked;
-                list.Add(item);
-            }
-            string audittrail;
-            if (picked == DateTime.MinValue)
-                audittrail = "Item unpicked";
-            else
-                audittrail = "Item picked " + picked.ToString("dd MMM yy");
-            new Client<RequisitionItem>().Save(list, audittrail);
-
-            UnPickedItems.Refresh(false, true);
-            Items.Refresh(false, true);
+            Requisitions.UpdateRow<Requisition, DateTime>(Requisitions.SelectedRows.First(), x => x.StockUpdated, _requisition.StockUpdated);
+            LoadRequisition();
         }
+
+        Progress.Close();
     }
 }

+ 1 - 1
prs.stores/RequisitionStore.cs

@@ -295,7 +295,7 @@ namespace Comal.Stores
                     ? holdingrow.Get<StockHolding, Guid>(c => c.Job.ID)
                     : Guid.Empty;
 
-                var qty = item.Quantity;
+                var qty = item.ActualQuantity;
                 var dimensions = item.Product.Dimensions;
 
                 var txnid = Guid.Empty;